1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * sparse/expression.c
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * Copyright (C) 2003 Transmeta Corp.
5f08c3bdfSopenharmony_ci *               2003-2004 Linus Torvalds
6f08c3bdfSopenharmony_ci *
7f08c3bdfSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
8f08c3bdfSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal
9f08c3bdfSopenharmony_ci * in the Software without restriction, including without limitation the rights
10f08c3bdfSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11f08c3bdfSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is
12f08c3bdfSopenharmony_ci * furnished to do so, subject to the following conditions:
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci * The above copyright notice and this permission notice shall be included in
15f08c3bdfSopenharmony_ci * all copies or substantial portions of the Software.
16f08c3bdfSopenharmony_ci *
17f08c3bdfSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18f08c3bdfSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f08c3bdfSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20f08c3bdfSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21f08c3bdfSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22f08c3bdfSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23f08c3bdfSopenharmony_ci * THE SOFTWARE.
24f08c3bdfSopenharmony_ci *
25f08c3bdfSopenharmony_ci * This is the expression parsing part of parsing C.
26f08c3bdfSopenharmony_ci */
27f08c3bdfSopenharmony_ci#include <stdarg.h>
28f08c3bdfSopenharmony_ci#include <stdlib.h>
29f08c3bdfSopenharmony_ci#include <stdio.h>
30f08c3bdfSopenharmony_ci#include <string.h>
31f08c3bdfSopenharmony_ci#include <ctype.h>
32f08c3bdfSopenharmony_ci#include <unistd.h>
33f08c3bdfSopenharmony_ci#include <fcntl.h>
34f08c3bdfSopenharmony_ci#include <errno.h>
35f08c3bdfSopenharmony_ci#include <limits.h>
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_ci#include "lib.h"
38f08c3bdfSopenharmony_ci#include "allocate.h"
39f08c3bdfSopenharmony_ci#include "token.h"
40f08c3bdfSopenharmony_ci#include "parse.h"
41f08c3bdfSopenharmony_ci#include "symbol.h"
42f08c3bdfSopenharmony_ci#include "scope.h"
43f08c3bdfSopenharmony_ci#include "expression.h"
44f08c3bdfSopenharmony_ci#include "target.h"
45f08c3bdfSopenharmony_ci#include "char.h"
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_ciALLOCATOR(type_expression, "type-expr-maps");
48f08c3bdfSopenharmony_ci
49f08c3bdfSopenharmony_cistatic int match_oplist(int op, ...)
50f08c3bdfSopenharmony_ci{
51f08c3bdfSopenharmony_ci	va_list args;
52f08c3bdfSopenharmony_ci	int nextop;
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_ci	va_start(args, op);
55f08c3bdfSopenharmony_ci	do {
56f08c3bdfSopenharmony_ci		nextop = va_arg(args, int);
57f08c3bdfSopenharmony_ci	} while (nextop != 0 && nextop != op);
58f08c3bdfSopenharmony_ci	va_end(args);
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci	return nextop != 0;
61f08c3bdfSopenharmony_ci}
62f08c3bdfSopenharmony_ci
63f08c3bdfSopenharmony_cistatic struct token *comma_expression(struct token *, struct expression **);
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_cistruct token *parens_expression(struct token *token, struct expression **expr, const char *where)
66f08c3bdfSopenharmony_ci{
67f08c3bdfSopenharmony_ci	struct token *p;
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_ci	token = expect(token, '(', where);
70f08c3bdfSopenharmony_ci	p = token;
71f08c3bdfSopenharmony_ci	if (match_op(token, '{')) {
72f08c3bdfSopenharmony_ci		struct expression *e = alloc_expression(token->pos, EXPR_STATEMENT);
73f08c3bdfSopenharmony_ci		struct statement *stmt = alloc_statement(token->pos, STMT_COMPOUND);
74f08c3bdfSopenharmony_ci		*expr = e;
75f08c3bdfSopenharmony_ci		e->statement = stmt;
76f08c3bdfSopenharmony_ci		start_label_scope();
77f08c3bdfSopenharmony_ci		token = compound_statement(token->next, stmt);
78f08c3bdfSopenharmony_ci		end_label_scope();
79f08c3bdfSopenharmony_ci		token = expect(token, '}', "at end of statement expression");
80f08c3bdfSopenharmony_ci	} else
81f08c3bdfSopenharmony_ci		token = parse_expression(token, expr);
82f08c3bdfSopenharmony_ci
83f08c3bdfSopenharmony_ci	if (token == p)
84f08c3bdfSopenharmony_ci		sparse_error(token->pos, "an expression is expected before ')'");
85f08c3bdfSopenharmony_ci	return expect(token, ')', where);
86f08c3bdfSopenharmony_ci}
87f08c3bdfSopenharmony_ci
88f08c3bdfSopenharmony_cistruct token *string_expression(struct token *token, struct expression **expr, const char *where)
89f08c3bdfSopenharmony_ci{
90f08c3bdfSopenharmony_ci	struct token *next = primary_expression(token, expr);
91f08c3bdfSopenharmony_ci
92f08c3bdfSopenharmony_ci	if (!*expr || (*expr)->type != EXPR_STRING) {
93f08c3bdfSopenharmony_ci		sparse_error(token->pos, "string literal expected for %s", where);
94f08c3bdfSopenharmony_ci		*expr = NULL;
95f08c3bdfSopenharmony_ci	}
96f08c3bdfSopenharmony_ci	return next;
97f08c3bdfSopenharmony_ci}
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_ci/*
100f08c3bdfSopenharmony_ci * Handle __func__, __FUNCTION__ and __PRETTY_FUNCTION__ token
101f08c3bdfSopenharmony_ci * conversion
102f08c3bdfSopenharmony_ci */
103f08c3bdfSopenharmony_cistatic struct symbol *handle_func(struct token *token)
104f08c3bdfSopenharmony_ci{
105f08c3bdfSopenharmony_ci	struct ident *ident = token->ident;
106f08c3bdfSopenharmony_ci	struct symbol *decl, *array;
107f08c3bdfSopenharmony_ci	struct string *string;
108f08c3bdfSopenharmony_ci	int len;
109f08c3bdfSopenharmony_ci
110f08c3bdfSopenharmony_ci	if (ident != &__func___ident &&
111f08c3bdfSopenharmony_ci	    ident != &__FUNCTION___ident &&
112f08c3bdfSopenharmony_ci	    ident != &__PRETTY_FUNCTION___ident)
113f08c3bdfSopenharmony_ci		return NULL;
114f08c3bdfSopenharmony_ci
115f08c3bdfSopenharmony_ci	if (!current_fn || !current_fn->ident)
116f08c3bdfSopenharmony_ci		return NULL;
117f08c3bdfSopenharmony_ci
118f08c3bdfSopenharmony_ci	/* OK, it's one of ours */
119f08c3bdfSopenharmony_ci	array = alloc_symbol(token->pos, SYM_ARRAY);
120f08c3bdfSopenharmony_ci	array->ctype.base_type = &char_ctype;
121f08c3bdfSopenharmony_ci	array->ctype.alignment = 1;
122f08c3bdfSopenharmony_ci	array->endpos = token->pos;
123f08c3bdfSopenharmony_ci	decl = alloc_symbol(token->pos, SYM_NODE);
124f08c3bdfSopenharmony_ci	decl->ctype.base_type = array;
125f08c3bdfSopenharmony_ci	decl->ctype.alignment = 1;
126f08c3bdfSopenharmony_ci	decl->ctype.modifiers = MOD_STATIC;
127f08c3bdfSopenharmony_ci	decl->endpos = token->pos;
128f08c3bdfSopenharmony_ci
129f08c3bdfSopenharmony_ci	/* NS_SYMBOL but in function-scope */
130f08c3bdfSopenharmony_ci	bind_symbol_with_scope(decl, ident, NS_SYMBOL, function_scope);
131f08c3bdfSopenharmony_ci
132f08c3bdfSopenharmony_ci	len = current_fn->ident->len;
133f08c3bdfSopenharmony_ci	string = __alloc_string(len + 1);
134f08c3bdfSopenharmony_ci	memcpy(string->data, current_fn->ident->name, len);
135f08c3bdfSopenharmony_ci	string->data[len] = 0;
136f08c3bdfSopenharmony_ci	string->length = len + 1;
137f08c3bdfSopenharmony_ci
138f08c3bdfSopenharmony_ci	decl->initializer = alloc_expression(token->pos, EXPR_STRING);
139f08c3bdfSopenharmony_ci	decl->initializer->string = string;
140f08c3bdfSopenharmony_ci	decl->initializer->ctype = decl;
141f08c3bdfSopenharmony_ci	decl->array_size = alloc_const_expression(token->pos, len + 1);
142f08c3bdfSopenharmony_ci	array->array_size = decl->array_size;
143f08c3bdfSopenharmony_ci	decl->bit_size = array->bit_size = bytes_to_bits(len + 1);
144f08c3bdfSopenharmony_ci
145f08c3bdfSopenharmony_ci	return decl;
146f08c3bdfSopenharmony_ci}
147f08c3bdfSopenharmony_ci
148f08c3bdfSopenharmony_cistatic struct token *parse_type(struct token *token, struct expression **tree)
149f08c3bdfSopenharmony_ci{
150f08c3bdfSopenharmony_ci	struct symbol *sym;
151f08c3bdfSopenharmony_ci	*tree = alloc_expression(token->pos, EXPR_TYPE);
152f08c3bdfSopenharmony_ci	token = typename(token, &sym, NULL);
153f08c3bdfSopenharmony_ci	if (sym->ident)
154f08c3bdfSopenharmony_ci		sparse_error(token->pos,
155f08c3bdfSopenharmony_ci			     "type expression should not include identifier "
156f08c3bdfSopenharmony_ci			     "\"%s\"", sym->ident->name);
157f08c3bdfSopenharmony_ci	(*tree)->symbol = sym;
158f08c3bdfSopenharmony_ci	return token;
159f08c3bdfSopenharmony_ci}
160f08c3bdfSopenharmony_ci
161f08c3bdfSopenharmony_cistatic struct token *builtin_types_compatible_p_expr(struct token *token,
162f08c3bdfSopenharmony_ci						     struct expression **tree)
163f08c3bdfSopenharmony_ci{
164f08c3bdfSopenharmony_ci	struct expression *expr = alloc_expression(
165f08c3bdfSopenharmony_ci		token->pos, EXPR_COMPARE);
166f08c3bdfSopenharmony_ci	expr->op = SPECIAL_EQUAL;
167f08c3bdfSopenharmony_ci	token = token->next;
168f08c3bdfSopenharmony_ci	if (!match_op(token, '('))
169f08c3bdfSopenharmony_ci		return expect(token, '(',
170f08c3bdfSopenharmony_ci			      "after __builtin_types_compatible_p");
171f08c3bdfSopenharmony_ci	token = token->next;
172f08c3bdfSopenharmony_ci	token = parse_type(token, &expr->left);
173f08c3bdfSopenharmony_ci	if (!match_op(token, ','))
174f08c3bdfSopenharmony_ci		return expect(token, ',',
175f08c3bdfSopenharmony_ci			      "in __builtin_types_compatible_p");
176f08c3bdfSopenharmony_ci	token = token->next;
177f08c3bdfSopenharmony_ci	token = parse_type(token, &expr->right);
178f08c3bdfSopenharmony_ci	if (!match_op(token, ')'))
179f08c3bdfSopenharmony_ci		return expect(token, ')',
180f08c3bdfSopenharmony_ci			      "at end of __builtin_types_compatible_p");
181f08c3bdfSopenharmony_ci	token = token->next;
182f08c3bdfSopenharmony_ci
183f08c3bdfSopenharmony_ci	*tree = expr;
184f08c3bdfSopenharmony_ci	return token;
185f08c3bdfSopenharmony_ci}
186f08c3bdfSopenharmony_ci
187f08c3bdfSopenharmony_cistatic struct token *builtin_offsetof_expr(struct token *token,
188f08c3bdfSopenharmony_ci					   struct expression **tree)
189f08c3bdfSopenharmony_ci{
190f08c3bdfSopenharmony_ci	struct expression *expr = NULL;
191f08c3bdfSopenharmony_ci	struct expression **p = &expr;
192f08c3bdfSopenharmony_ci	struct symbol *sym;
193f08c3bdfSopenharmony_ci	int op = '.';
194f08c3bdfSopenharmony_ci
195f08c3bdfSopenharmony_ci	token = token->next;
196f08c3bdfSopenharmony_ci	if (!match_op(token, '('))
197f08c3bdfSopenharmony_ci		return expect(token, '(', "after __builtin_offset");
198f08c3bdfSopenharmony_ci
199f08c3bdfSopenharmony_ci	token = token->next;
200f08c3bdfSopenharmony_ci	token = typename(token, &sym, NULL);
201f08c3bdfSopenharmony_ci	if (sym->ident)
202f08c3bdfSopenharmony_ci		sparse_error(token->pos,
203f08c3bdfSopenharmony_ci			     "type expression should not include identifier "
204f08c3bdfSopenharmony_ci			     "\"%s\"", sym->ident->name);
205f08c3bdfSopenharmony_ci
206f08c3bdfSopenharmony_ci	if (!match_op(token, ','))
207f08c3bdfSopenharmony_ci		return expect(token, ',', "in __builtin_offset");
208f08c3bdfSopenharmony_ci
209f08c3bdfSopenharmony_ci	while (1) {
210f08c3bdfSopenharmony_ci		struct expression *e;
211f08c3bdfSopenharmony_ci		switch (op) {
212f08c3bdfSopenharmony_ci		case ')':
213f08c3bdfSopenharmony_ci			expr->in = sym;
214f08c3bdfSopenharmony_ci			*tree = expr;
215f08c3bdfSopenharmony_ci		default:
216f08c3bdfSopenharmony_ci			return expect(token, ')', "at end of __builtin_offset");
217f08c3bdfSopenharmony_ci		case SPECIAL_DEREFERENCE:
218f08c3bdfSopenharmony_ci			e = alloc_expression(token->pos, EXPR_OFFSETOF);
219f08c3bdfSopenharmony_ci			e->op = '[';
220f08c3bdfSopenharmony_ci			*p = e;
221f08c3bdfSopenharmony_ci			p = &e->down;
222f08c3bdfSopenharmony_ci			/* fall through */
223f08c3bdfSopenharmony_ci		case '.':
224f08c3bdfSopenharmony_ci			token = token->next;
225f08c3bdfSopenharmony_ci			e = alloc_expression(token->pos, EXPR_OFFSETOF);
226f08c3bdfSopenharmony_ci			e->op = '.';
227f08c3bdfSopenharmony_ci			if (token_type(token) != TOKEN_IDENT) {
228f08c3bdfSopenharmony_ci				sparse_error(token->pos, "Expected member name");
229f08c3bdfSopenharmony_ci				return token;
230f08c3bdfSopenharmony_ci			}
231f08c3bdfSopenharmony_ci			e->ident = token->ident;
232f08c3bdfSopenharmony_ci			token = token->next;
233f08c3bdfSopenharmony_ci			break;
234f08c3bdfSopenharmony_ci		case '[':
235f08c3bdfSopenharmony_ci			token = token->next;
236f08c3bdfSopenharmony_ci			e = alloc_expression(token->pos, EXPR_OFFSETOF);
237f08c3bdfSopenharmony_ci			e->op = '[';
238f08c3bdfSopenharmony_ci			token = parse_expression(token, &e->index);
239f08c3bdfSopenharmony_ci			token = expect(token, ']',
240f08c3bdfSopenharmony_ci					"at end of array dereference");
241f08c3bdfSopenharmony_ci			if (!e->index)
242f08c3bdfSopenharmony_ci				return token;
243f08c3bdfSopenharmony_ci		}
244f08c3bdfSopenharmony_ci		*p = e;
245f08c3bdfSopenharmony_ci		p = &e->down;
246f08c3bdfSopenharmony_ci		op = token_type(token) == TOKEN_SPECIAL ? token->special : 0;
247f08c3bdfSopenharmony_ci	}
248f08c3bdfSopenharmony_ci}
249f08c3bdfSopenharmony_ci
250f08c3bdfSopenharmony_ci#ifndef ULLONG_MAX
251f08c3bdfSopenharmony_ci#define ULLONG_MAX (~0ULL)
252f08c3bdfSopenharmony_ci#endif
253f08c3bdfSopenharmony_ci
254f08c3bdfSopenharmony_cistatic unsigned long long parse_num(const char *nptr, char **end)
255f08c3bdfSopenharmony_ci{
256f08c3bdfSopenharmony_ci	if (nptr[0] == '0' && tolower((unsigned char)nptr[1]) == 'b')
257f08c3bdfSopenharmony_ci		return strtoull(&nptr[2], end, 2);
258f08c3bdfSopenharmony_ci	return strtoull(nptr, end, 0);
259f08c3bdfSopenharmony_ci}
260f08c3bdfSopenharmony_ci
261f08c3bdfSopenharmony_cistatic void get_number_value(struct expression *expr, struct token *token)
262f08c3bdfSopenharmony_ci{
263f08c3bdfSopenharmony_ci	const char *str = token->number;
264f08c3bdfSopenharmony_ci	unsigned long long value;
265f08c3bdfSopenharmony_ci	char *end;
266f08c3bdfSopenharmony_ci	int size = 0, want_unsigned = 0;
267f08c3bdfSopenharmony_ci	int overflow = 0, do_warn = 0;
268f08c3bdfSopenharmony_ci	int try_unsigned = 1;
269f08c3bdfSopenharmony_ci	int bits;
270f08c3bdfSopenharmony_ci
271f08c3bdfSopenharmony_ci	errno = 0;
272f08c3bdfSopenharmony_ci	value = parse_num(str, &end);
273f08c3bdfSopenharmony_ci	if (end == str)
274f08c3bdfSopenharmony_ci		goto Float;
275f08c3bdfSopenharmony_ci	if (value == ULLONG_MAX && errno == ERANGE)
276f08c3bdfSopenharmony_ci		overflow = 1;
277f08c3bdfSopenharmony_ci	while (1) {
278f08c3bdfSopenharmony_ci		char c = *end++;
279f08c3bdfSopenharmony_ci		if (!c) {
280f08c3bdfSopenharmony_ci			break;
281f08c3bdfSopenharmony_ci		} else if (c == 'u' || c == 'U') {
282f08c3bdfSopenharmony_ci			if (want_unsigned)
283f08c3bdfSopenharmony_ci				goto Enoint;
284f08c3bdfSopenharmony_ci			want_unsigned = 1;
285f08c3bdfSopenharmony_ci		} else if (c == 'l' || c == 'L') {
286f08c3bdfSopenharmony_ci			if (size)
287f08c3bdfSopenharmony_ci				goto Enoint;
288f08c3bdfSopenharmony_ci			size = 1;
289f08c3bdfSopenharmony_ci			if (*end == c) {
290f08c3bdfSopenharmony_ci				size = 2;
291f08c3bdfSopenharmony_ci				end++;
292f08c3bdfSopenharmony_ci			}
293f08c3bdfSopenharmony_ci		} else
294f08c3bdfSopenharmony_ci			goto Float;
295f08c3bdfSopenharmony_ci	}
296f08c3bdfSopenharmony_ci	if (overflow)
297f08c3bdfSopenharmony_ci		goto Eoverflow;
298f08c3bdfSopenharmony_ci	/* OK, it's a valid integer */
299f08c3bdfSopenharmony_ci	/* decimals can be unsigned only if directly specified as such */
300f08c3bdfSopenharmony_ci	if (str[0] != '0' && !want_unsigned)
301f08c3bdfSopenharmony_ci		try_unsigned = 0;
302f08c3bdfSopenharmony_ci	if (!size) {
303f08c3bdfSopenharmony_ci		bits = bits_in_int - 1;
304f08c3bdfSopenharmony_ci		if (!(value & (~1ULL << bits))) {
305f08c3bdfSopenharmony_ci			if (!(value & (1ULL << bits))) {
306f08c3bdfSopenharmony_ci				goto got_it;
307f08c3bdfSopenharmony_ci			} else if (try_unsigned) {
308f08c3bdfSopenharmony_ci				want_unsigned = 1;
309f08c3bdfSopenharmony_ci				goto got_it;
310f08c3bdfSopenharmony_ci			}
311f08c3bdfSopenharmony_ci		}
312f08c3bdfSopenharmony_ci		size = 1;
313f08c3bdfSopenharmony_ci		do_warn = 1;
314f08c3bdfSopenharmony_ci	}
315f08c3bdfSopenharmony_ci	if (size < 2) {
316f08c3bdfSopenharmony_ci		bits = bits_in_long - 1;
317f08c3bdfSopenharmony_ci		if (!(value & (~1ULL << bits))) {
318f08c3bdfSopenharmony_ci			if (!(value & (1ULL << bits))) {
319f08c3bdfSopenharmony_ci				goto got_it;
320f08c3bdfSopenharmony_ci			} else if (try_unsigned) {
321f08c3bdfSopenharmony_ci				want_unsigned = 1;
322f08c3bdfSopenharmony_ci				goto got_it;
323f08c3bdfSopenharmony_ci			}
324f08c3bdfSopenharmony_ci			do_warn |= 2;
325f08c3bdfSopenharmony_ci		}
326f08c3bdfSopenharmony_ci		size = 2;
327f08c3bdfSopenharmony_ci		do_warn |= 1;
328f08c3bdfSopenharmony_ci	}
329f08c3bdfSopenharmony_ci	bits = bits_in_longlong - 1;
330f08c3bdfSopenharmony_ci	if (value & (~1ULL << bits))
331f08c3bdfSopenharmony_ci		goto Eoverflow;
332f08c3bdfSopenharmony_ci	if (!(value & (1ULL << bits)))
333f08c3bdfSopenharmony_ci		goto got_it;
334f08c3bdfSopenharmony_ci	if (!try_unsigned)
335f08c3bdfSopenharmony_ci		warning(expr->pos, "decimal constant %s is too big for long long",
336f08c3bdfSopenharmony_ci			show_token(token));
337f08c3bdfSopenharmony_ci	want_unsigned = 1;
338f08c3bdfSopenharmony_cigot_it:
339f08c3bdfSopenharmony_ci	if (do_warn && Wconstant_suffix)
340f08c3bdfSopenharmony_ci		warning(expr->pos, "constant %s is so big it is%s%s%s",
341f08c3bdfSopenharmony_ci			show_token(token),
342f08c3bdfSopenharmony_ci			want_unsigned ? " unsigned":"",
343f08c3bdfSopenharmony_ci			size > 0 ? " long":"",
344f08c3bdfSopenharmony_ci			size > 1 ? " long":"");
345f08c3bdfSopenharmony_ci	if (do_warn & 2)
346f08c3bdfSopenharmony_ci		warning(expr->pos,
347f08c3bdfSopenharmony_ci			"decimal constant %s is between LONG_MAX and ULONG_MAX."
348f08c3bdfSopenharmony_ci			" For C99 that means long long, C90 compilers are very "
349f08c3bdfSopenharmony_ci			"likely to produce unsigned long (and a warning) here",
350f08c3bdfSopenharmony_ci			show_token(token));
351f08c3bdfSopenharmony_ci        expr->type = EXPR_VALUE;
352f08c3bdfSopenharmony_ci	expr->flags = CEF_SET_INT;
353f08c3bdfSopenharmony_ci        expr->ctype = ctype_integer(size, want_unsigned);
354f08c3bdfSopenharmony_ci        expr->value = value;
355f08c3bdfSopenharmony_ci	return;
356f08c3bdfSopenharmony_ciEoverflow:
357f08c3bdfSopenharmony_ci	error_die(expr->pos, "constant %s is too big even for unsigned long long",
358f08c3bdfSopenharmony_ci			show_token(token));
359f08c3bdfSopenharmony_ci	return;
360f08c3bdfSopenharmony_ciFloat:
361f08c3bdfSopenharmony_ci	expr->fvalue = string_to_ld(str, &end);
362f08c3bdfSopenharmony_ci	if (str == end)
363f08c3bdfSopenharmony_ci		goto Enoint;
364f08c3bdfSopenharmony_ci
365f08c3bdfSopenharmony_ci	if (*end && end[1])
366f08c3bdfSopenharmony_ci		goto Enoint;
367f08c3bdfSopenharmony_ci
368f08c3bdfSopenharmony_ci	if (*end == 'f' || *end == 'F')
369f08c3bdfSopenharmony_ci		expr->ctype = &float_ctype;
370f08c3bdfSopenharmony_ci	else if (*end == 'l' || *end == 'L')
371f08c3bdfSopenharmony_ci		expr->ctype = &ldouble_ctype;
372f08c3bdfSopenharmony_ci	else if (!*end)
373f08c3bdfSopenharmony_ci		expr->ctype = &double_ctype;
374f08c3bdfSopenharmony_ci	else
375f08c3bdfSopenharmony_ci		goto Enoint;
376f08c3bdfSopenharmony_ci
377f08c3bdfSopenharmony_ci	expr->flags = CEF_SET_FLOAT;
378f08c3bdfSopenharmony_ci	expr->type = EXPR_FVALUE;
379f08c3bdfSopenharmony_ci	return;
380f08c3bdfSopenharmony_ci
381f08c3bdfSopenharmony_ciEnoint:
382f08c3bdfSopenharmony_ci	sparse_error(expr->pos, "constant %s is not a valid number", show_token(token));
383f08c3bdfSopenharmony_ci	expr->type = EXPR_VALUE;
384f08c3bdfSopenharmony_ci	expr->value = 0;
385f08c3bdfSopenharmony_ci	expr->ctype = &int_ctype;
386f08c3bdfSopenharmony_ci}
387f08c3bdfSopenharmony_ci
388f08c3bdfSopenharmony_cistatic struct token *generic_selection(struct token *token, struct expression **tree)
389f08c3bdfSopenharmony_ci{
390f08c3bdfSopenharmony_ci	struct expression *expr = alloc_expression(token->pos, EXPR_GENERIC);
391f08c3bdfSopenharmony_ci	struct type_expression **last = &expr->map;
392f08c3bdfSopenharmony_ci
393f08c3bdfSopenharmony_ci	token = expect(token, '(', "after '_Generic'");
394f08c3bdfSopenharmony_ci	token = assignment_expression(token, &expr->control);
395f08c3bdfSopenharmony_ci	if (!match_op(token, ',')) {
396f08c3bdfSopenharmony_ci		goto end;
397f08c3bdfSopenharmony_ci	}
398f08c3bdfSopenharmony_ci	while (match_op(token, ',')) {
399f08c3bdfSopenharmony_ci		token = token->next;
400f08c3bdfSopenharmony_ci		if (lookup_type(token)) {
401f08c3bdfSopenharmony_ci			struct type_expression *map = __alloc_type_expression(0);
402f08c3bdfSopenharmony_ci			token = typename(token, &map->type, NULL);
403f08c3bdfSopenharmony_ci			token = expect(token, ':', "after typename");
404f08c3bdfSopenharmony_ci			token = assignment_expression(token, &map->expr);
405f08c3bdfSopenharmony_ci			*last = map;
406f08c3bdfSopenharmony_ci			last = &map->next;
407f08c3bdfSopenharmony_ci		} else if (match_ident(token, &default_ident)) {
408f08c3bdfSopenharmony_ci			if (expr->def) {
409f08c3bdfSopenharmony_ci				warning(token->pos, "multiple default in generic expression");
410f08c3bdfSopenharmony_ci				info(expr->def->pos, "note: previous was here");
411f08c3bdfSopenharmony_ci			}
412f08c3bdfSopenharmony_ci			token = token->next;
413f08c3bdfSopenharmony_ci			token = expect(token, ':', "after typename");
414f08c3bdfSopenharmony_ci			token = assignment_expression(token, &expr->def);
415f08c3bdfSopenharmony_ci		}
416f08c3bdfSopenharmony_ci	}
417f08c3bdfSopenharmony_ciend:
418f08c3bdfSopenharmony_ci	*tree = expr;
419f08c3bdfSopenharmony_ci	return expect(token, ')', "after expression");
420f08c3bdfSopenharmony_ci}
421f08c3bdfSopenharmony_ci
422f08c3bdfSopenharmony_cistruct token *primary_expression(struct token *token, struct expression **tree)
423f08c3bdfSopenharmony_ci{
424f08c3bdfSopenharmony_ci	struct expression *expr = NULL;
425f08c3bdfSopenharmony_ci
426f08c3bdfSopenharmony_ci	switch (token_type(token)) {
427f08c3bdfSopenharmony_ci	case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3:
428f08c3bdfSopenharmony_ci		expr = alloc_expression(token->pos, EXPR_VALUE);
429f08c3bdfSopenharmony_ci		expr->flags = CEF_SET_CHAR;
430f08c3bdfSopenharmony_ci		expr->ctype = token_type(token) < TOKEN_WIDE_CHAR ? &int_ctype : &long_ctype;
431f08c3bdfSopenharmony_ci		get_char_constant(token, &expr->value);
432f08c3bdfSopenharmony_ci		token = token->next;
433f08c3bdfSopenharmony_ci		break;
434f08c3bdfSopenharmony_ci
435f08c3bdfSopenharmony_ci	case TOKEN_NUMBER:
436f08c3bdfSopenharmony_ci		expr = alloc_expression(token->pos, EXPR_VALUE);
437f08c3bdfSopenharmony_ci		get_number_value(expr, token); /* will see if it's an integer */
438f08c3bdfSopenharmony_ci		token = token->next;
439f08c3bdfSopenharmony_ci		break;
440f08c3bdfSopenharmony_ci
441f08c3bdfSopenharmony_ci	case TOKEN_ZERO_IDENT: {
442f08c3bdfSopenharmony_ci		expr = alloc_expression(token->pos, EXPR_SYMBOL);
443f08c3bdfSopenharmony_ci		expr->flags = CEF_SET_INT;
444f08c3bdfSopenharmony_ci		expr->ctype = &int_ctype;
445f08c3bdfSopenharmony_ci		expr->symbol = &zero_int;
446f08c3bdfSopenharmony_ci		expr->symbol_name = token->ident;
447f08c3bdfSopenharmony_ci		token = token->next;
448f08c3bdfSopenharmony_ci		break;
449f08c3bdfSopenharmony_ci	}
450f08c3bdfSopenharmony_ci
451f08c3bdfSopenharmony_ci	case TOKEN_IDENT: {
452f08c3bdfSopenharmony_ci		struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
453f08c3bdfSopenharmony_ci		struct token *next = token->next;
454f08c3bdfSopenharmony_ci
455f08c3bdfSopenharmony_ci		if (!sym) {
456f08c3bdfSopenharmony_ci			sym = handle_func(token);
457f08c3bdfSopenharmony_ci			if (token->ident == &__builtin_types_compatible_p_ident) {
458f08c3bdfSopenharmony_ci				token = builtin_types_compatible_p_expr(token, &expr);
459f08c3bdfSopenharmony_ci				break;
460f08c3bdfSopenharmony_ci			}
461f08c3bdfSopenharmony_ci			if (token->ident == &__builtin_offsetof_ident) {
462f08c3bdfSopenharmony_ci				token = builtin_offsetof_expr(token, &expr);
463f08c3bdfSopenharmony_ci				break;
464f08c3bdfSopenharmony_ci			}
465f08c3bdfSopenharmony_ci			if (token->ident == &_Generic_ident) {
466f08c3bdfSopenharmony_ci				token = generic_selection(token->next, &expr);
467f08c3bdfSopenharmony_ci				break;
468f08c3bdfSopenharmony_ci			}
469f08c3bdfSopenharmony_ci		} else if (sym->enum_member) {
470f08c3bdfSopenharmony_ci			expr = alloc_expression(token->pos, EXPR_VALUE);
471f08c3bdfSopenharmony_ci			*expr = *sym->initializer;
472f08c3bdfSopenharmony_ci			/* we want the right position reported, thus the copy */
473f08c3bdfSopenharmony_ci			expr->pos = token->pos;
474f08c3bdfSopenharmony_ci			expr->flags = CEF_SET_ENUM;
475f08c3bdfSopenharmony_ci			token = next;
476f08c3bdfSopenharmony_ci			break;
477f08c3bdfSopenharmony_ci		}
478f08c3bdfSopenharmony_ci
479f08c3bdfSopenharmony_ci		expr = alloc_expression(token->pos, EXPR_SYMBOL);
480f08c3bdfSopenharmony_ci
481f08c3bdfSopenharmony_ci		/*
482f08c3bdfSopenharmony_ci		 * We support types as real first-class citizens, with type
483f08c3bdfSopenharmony_ci		 * comparisons etc:
484f08c3bdfSopenharmony_ci		 *
485f08c3bdfSopenharmony_ci		 *	if (typeof(a) == int) ..
486f08c3bdfSopenharmony_ci		 */
487f08c3bdfSopenharmony_ci		if (sym && sym->namespace == NS_TYPEDEF) {
488f08c3bdfSopenharmony_ci			sparse_error(token->pos, "typename in expression");
489f08c3bdfSopenharmony_ci			sym = NULL;
490f08c3bdfSopenharmony_ci		}
491f08c3bdfSopenharmony_ci		expr->symbol_name = token->ident;
492f08c3bdfSopenharmony_ci		expr->symbol = sym;
493f08c3bdfSopenharmony_ci
494f08c3bdfSopenharmony_ci		/*
495f08c3bdfSopenharmony_ci		 * A pointer to an lvalue designating a static storage
496f08c3bdfSopenharmony_ci		 * duration object is an address constant [6.6(9)].
497f08c3bdfSopenharmony_ci		 */
498f08c3bdfSopenharmony_ci		if (sym && (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_STATIC)))
499f08c3bdfSopenharmony_ci			expr->flags = CEF_ADDR;
500f08c3bdfSopenharmony_ci
501f08c3bdfSopenharmony_ci		token = next;
502f08c3bdfSopenharmony_ci		break;
503f08c3bdfSopenharmony_ci	}
504f08c3bdfSopenharmony_ci
505f08c3bdfSopenharmony_ci	case TOKEN_STRING:
506f08c3bdfSopenharmony_ci	case TOKEN_WIDE_STRING:
507f08c3bdfSopenharmony_ci		expr = alloc_expression(token->pos, EXPR_STRING);
508f08c3bdfSopenharmony_ci		token = get_string_constant(token, expr);
509f08c3bdfSopenharmony_ci		break;
510f08c3bdfSopenharmony_ci
511f08c3bdfSopenharmony_ci	case TOKEN_SPECIAL:
512f08c3bdfSopenharmony_ci		if (token->special == '(') {
513f08c3bdfSopenharmony_ci			expr = alloc_expression(token->pos, EXPR_PREOP);
514f08c3bdfSopenharmony_ci			expr->op = '(';
515f08c3bdfSopenharmony_ci			token = parens_expression(token, &expr->unop, "in expression");
516f08c3bdfSopenharmony_ci			break;
517f08c3bdfSopenharmony_ci		}
518f08c3bdfSopenharmony_ci		if (token->special == '[' && lookup_type(token->next)) {
519f08c3bdfSopenharmony_ci			expr = alloc_expression(token->pos, EXPR_TYPE);
520f08c3bdfSopenharmony_ci			token = typename(token->next, &expr->symbol, NULL);
521f08c3bdfSopenharmony_ci			token = expect(token, ']', "in type expression");
522f08c3bdfSopenharmony_ci			break;
523f08c3bdfSopenharmony_ci		}
524f08c3bdfSopenharmony_ci
525f08c3bdfSopenharmony_ci	default:
526f08c3bdfSopenharmony_ci		;
527f08c3bdfSopenharmony_ci	}
528f08c3bdfSopenharmony_ci	*tree = expr;
529f08c3bdfSopenharmony_ci	return token;
530f08c3bdfSopenharmony_ci}
531f08c3bdfSopenharmony_ci
532f08c3bdfSopenharmony_cistatic struct token *expression_list(struct token *token, struct expression_list **list)
533f08c3bdfSopenharmony_ci{
534f08c3bdfSopenharmony_ci	while (!match_op(token, ')')) {
535f08c3bdfSopenharmony_ci		struct expression *expr = NULL;
536f08c3bdfSopenharmony_ci		token = assignment_expression(token, &expr);
537f08c3bdfSopenharmony_ci		if (!expr)
538f08c3bdfSopenharmony_ci			break;
539f08c3bdfSopenharmony_ci		add_expression(list, expr);
540f08c3bdfSopenharmony_ci		if (!match_op(token, ','))
541f08c3bdfSopenharmony_ci			break;
542f08c3bdfSopenharmony_ci		token = token->next;
543f08c3bdfSopenharmony_ci	}
544f08c3bdfSopenharmony_ci	return token;
545f08c3bdfSopenharmony_ci}
546f08c3bdfSopenharmony_ci
547f08c3bdfSopenharmony_ci/*
548f08c3bdfSopenharmony_ci * extend to deal with the ambiguous C grammar for parsing
549f08c3bdfSopenharmony_ci * a cast expressions followed by an initializer.
550f08c3bdfSopenharmony_ci */
551f08c3bdfSopenharmony_cistatic struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr)
552f08c3bdfSopenharmony_ci{
553f08c3bdfSopenharmony_ci	struct expression *expr = cast_init_expr;
554f08c3bdfSopenharmony_ci
555f08c3bdfSopenharmony_ci	if (!expr)
556f08c3bdfSopenharmony_ci		token = primary_expression(token, &expr);
557f08c3bdfSopenharmony_ci
558f08c3bdfSopenharmony_ci	while (expr && token_type(token) == TOKEN_SPECIAL) {
559f08c3bdfSopenharmony_ci		switch (token->special) {
560f08c3bdfSopenharmony_ci		case '[': {			/* Array dereference */
561f08c3bdfSopenharmony_ci			struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
562f08c3bdfSopenharmony_ci			struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
563f08c3bdfSopenharmony_ci
564f08c3bdfSopenharmony_ci			deref->op = '*';
565f08c3bdfSopenharmony_ci			deref->unop = add;
566f08c3bdfSopenharmony_ci
567f08c3bdfSopenharmony_ci			add->op = '+';
568f08c3bdfSopenharmony_ci			add->left = expr;
569f08c3bdfSopenharmony_ci			token = parse_expression(token->next, &add->right);
570f08c3bdfSopenharmony_ci			token = expect(token, ']', "at end of array dereference");
571f08c3bdfSopenharmony_ci			expr = deref;
572f08c3bdfSopenharmony_ci			continue;
573f08c3bdfSopenharmony_ci		}
574f08c3bdfSopenharmony_ci		case SPECIAL_INCREMENT:		/* Post-increment */
575f08c3bdfSopenharmony_ci		case SPECIAL_DECREMENT:	{	/* Post-decrement */
576f08c3bdfSopenharmony_ci			struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
577f08c3bdfSopenharmony_ci			post->op = token->special;
578f08c3bdfSopenharmony_ci			post->unop = expr;
579f08c3bdfSopenharmony_ci			expr = post;
580f08c3bdfSopenharmony_ci			token = token->next;
581f08c3bdfSopenharmony_ci			continue;
582f08c3bdfSopenharmony_ci		}
583f08c3bdfSopenharmony_ci		case SPECIAL_DEREFERENCE: {	/* Structure pointer member dereference */
584f08c3bdfSopenharmony_ci			/* "x->y" is just shorthand for "(*x).y" */
585f08c3bdfSopenharmony_ci			struct expression *inner = alloc_expression(token->pos, EXPR_PREOP);
586f08c3bdfSopenharmony_ci			inner->op = '*';
587f08c3bdfSopenharmony_ci			inner->unop = expr;
588f08c3bdfSopenharmony_ci			expr = inner;
589f08c3bdfSopenharmony_ci		}
590f08c3bdfSopenharmony_ci		/* Fall through!! */
591f08c3bdfSopenharmony_ci		case '.': {			/* Structure member dereference */
592f08c3bdfSopenharmony_ci			struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
593f08c3bdfSopenharmony_ci			deref->op = '.';
594f08c3bdfSopenharmony_ci			deref->deref = expr;
595f08c3bdfSopenharmony_ci			token = token->next;
596f08c3bdfSopenharmony_ci			if (token_type(token) != TOKEN_IDENT) {
597f08c3bdfSopenharmony_ci				sparse_error(token->pos, "Expected member name");
598f08c3bdfSopenharmony_ci				break;
599f08c3bdfSopenharmony_ci			}
600f08c3bdfSopenharmony_ci			deref->member = token->ident;
601f08c3bdfSopenharmony_ci			token = token->next;
602f08c3bdfSopenharmony_ci			expr = deref;
603f08c3bdfSopenharmony_ci			continue;
604f08c3bdfSopenharmony_ci		}
605f08c3bdfSopenharmony_ci
606f08c3bdfSopenharmony_ci		case '(': {			/* Function call */
607f08c3bdfSopenharmony_ci			struct expression *call = alloc_expression(token->pos, EXPR_CALL);
608f08c3bdfSopenharmony_ci			call->op = '(';
609f08c3bdfSopenharmony_ci			call->fn = expr;
610f08c3bdfSopenharmony_ci			token = expression_list(token->next, &call->args);
611f08c3bdfSopenharmony_ci			token = expect(token, ')', "in function call");
612f08c3bdfSopenharmony_ci			expr = call;
613f08c3bdfSopenharmony_ci			continue;
614f08c3bdfSopenharmony_ci		}
615f08c3bdfSopenharmony_ci
616f08c3bdfSopenharmony_ci		default:
617f08c3bdfSopenharmony_ci			break;
618f08c3bdfSopenharmony_ci		}
619f08c3bdfSopenharmony_ci		break;
620f08c3bdfSopenharmony_ci	}
621f08c3bdfSopenharmony_ci	*tree = expr;
622f08c3bdfSopenharmony_ci	return token;
623f08c3bdfSopenharmony_ci}
624f08c3bdfSopenharmony_ci
625f08c3bdfSopenharmony_cistatic struct token *cast_expression(struct token *token, struct expression **tree);
626f08c3bdfSopenharmony_cistatic struct token *unary_expression(struct token *token, struct expression **tree);
627f08c3bdfSopenharmony_ci
628f08c3bdfSopenharmony_cistatic struct token *type_info_expression(struct token *token,
629f08c3bdfSopenharmony_ci	struct expression **tree, int type)
630f08c3bdfSopenharmony_ci{
631f08c3bdfSopenharmony_ci	struct expression *expr = alloc_expression(token->pos, type);
632f08c3bdfSopenharmony_ci	struct token *p;
633f08c3bdfSopenharmony_ci
634f08c3bdfSopenharmony_ci	*tree = expr;
635f08c3bdfSopenharmony_ci	expr->flags = CEF_SET_ICE; /* XXX: VLA support will need that changed */
636f08c3bdfSopenharmony_ci	token = token->next;
637f08c3bdfSopenharmony_ci	if (!match_op(token, '(') || !lookup_type(token->next))
638f08c3bdfSopenharmony_ci		return unary_expression(token, &expr->cast_expression);
639f08c3bdfSopenharmony_ci	p = token;
640f08c3bdfSopenharmony_ci	token = typename(token->next, &expr->cast_type, NULL);
641f08c3bdfSopenharmony_ci
642f08c3bdfSopenharmony_ci	if (!match_op(token, ')')) {
643f08c3bdfSopenharmony_ci		static const char * error[] = {
644f08c3bdfSopenharmony_ci			[EXPR_SIZEOF] = "at end of sizeof",
645f08c3bdfSopenharmony_ci			[EXPR_ALIGNOF] = "at end of __alignof__",
646f08c3bdfSopenharmony_ci			[EXPR_PTRSIZEOF] = "at end of __sizeof_ptr__"
647f08c3bdfSopenharmony_ci		};
648f08c3bdfSopenharmony_ci		return expect(token, ')', error[type]);
649f08c3bdfSopenharmony_ci	}
650f08c3bdfSopenharmony_ci
651f08c3bdfSopenharmony_ci	token = token->next;
652f08c3bdfSopenharmony_ci	/*
653f08c3bdfSopenharmony_ci	 * C99 ambiguity: the typename might have been the beginning
654f08c3bdfSopenharmony_ci	 * of a typed initializer expression..
655f08c3bdfSopenharmony_ci	 */
656f08c3bdfSopenharmony_ci	if (match_op(token, '{')) {
657f08c3bdfSopenharmony_ci		struct expression *cast = alloc_expression(p->pos, EXPR_CAST);
658f08c3bdfSopenharmony_ci		cast->cast_type = expr->cast_type;
659f08c3bdfSopenharmony_ci		expr->cast_type = NULL;
660f08c3bdfSopenharmony_ci		expr->cast_expression = cast;
661f08c3bdfSopenharmony_ci		token = initializer(&cast->cast_expression, token);
662f08c3bdfSopenharmony_ci		token = postfix_expression(token, &expr->cast_expression, cast);
663f08c3bdfSopenharmony_ci	}
664f08c3bdfSopenharmony_ci	return token;
665f08c3bdfSopenharmony_ci}
666f08c3bdfSopenharmony_ci
667f08c3bdfSopenharmony_cistatic struct token *unary_expression(struct token *token, struct expression **tree)
668f08c3bdfSopenharmony_ci{
669f08c3bdfSopenharmony_ci	if (token_type(token) == TOKEN_IDENT) {
670f08c3bdfSopenharmony_ci		struct ident *ident = token->ident;
671f08c3bdfSopenharmony_ci		if (ident->reserved) {
672f08c3bdfSopenharmony_ci			static const struct {
673f08c3bdfSopenharmony_ci				struct ident *id;
674f08c3bdfSopenharmony_ci				int type;
675f08c3bdfSopenharmony_ci			} type_information[] = {
676f08c3bdfSopenharmony_ci				{ &sizeof_ident, EXPR_SIZEOF },
677f08c3bdfSopenharmony_ci				{ &__alignof___ident, EXPR_ALIGNOF },
678f08c3bdfSopenharmony_ci				{ &__alignof_ident, EXPR_ALIGNOF },
679f08c3bdfSopenharmony_ci				{ &_Alignof_ident, EXPR_ALIGNOF },
680f08c3bdfSopenharmony_ci				{ &__sizeof_ptr___ident, EXPR_PTRSIZEOF },
681f08c3bdfSopenharmony_ci			};
682f08c3bdfSopenharmony_ci			int i;
683f08c3bdfSopenharmony_ci			for (i = 0; i < ARRAY_SIZE(type_information); i++) {
684f08c3bdfSopenharmony_ci				if (ident == type_information[i].id)
685f08c3bdfSopenharmony_ci					return type_info_expression(token, tree, type_information[i].type);
686f08c3bdfSopenharmony_ci			}
687f08c3bdfSopenharmony_ci		}
688f08c3bdfSopenharmony_ci	}
689f08c3bdfSopenharmony_ci
690f08c3bdfSopenharmony_ci	if (token_type(token) == TOKEN_SPECIAL) {
691f08c3bdfSopenharmony_ci		if (match_oplist(token->special,
692f08c3bdfSopenharmony_ci		    SPECIAL_INCREMENT, SPECIAL_DECREMENT,
693f08c3bdfSopenharmony_ci		    '&', '*', 0)) {
694f08c3bdfSopenharmony_ci		    	struct expression *unop;
695f08c3bdfSopenharmony_ci			struct expression *unary;
696f08c3bdfSopenharmony_ci			struct token *next;
697f08c3bdfSopenharmony_ci
698f08c3bdfSopenharmony_ci			next = cast_expression(token->next, &unop);
699f08c3bdfSopenharmony_ci			if (!unop) {
700f08c3bdfSopenharmony_ci				sparse_error(token->pos, "Syntax error in unary expression");
701f08c3bdfSopenharmony_ci				*tree = NULL;
702f08c3bdfSopenharmony_ci				return next;
703f08c3bdfSopenharmony_ci			}
704f08c3bdfSopenharmony_ci			unary = alloc_expression(token->pos, EXPR_PREOP);
705f08c3bdfSopenharmony_ci			unary->op = token->special;
706f08c3bdfSopenharmony_ci			unary->unop = unop;
707f08c3bdfSopenharmony_ci			*tree = unary;
708f08c3bdfSopenharmony_ci			return next;
709f08c3bdfSopenharmony_ci		}
710f08c3bdfSopenharmony_ci		/* possibly constant ones */
711f08c3bdfSopenharmony_ci		if (match_oplist(token->special, '+', '-', '~', '!', 0)) {
712f08c3bdfSopenharmony_ci		    	struct expression *unop;
713f08c3bdfSopenharmony_ci			struct expression *unary;
714f08c3bdfSopenharmony_ci			struct token *next;
715f08c3bdfSopenharmony_ci
716f08c3bdfSopenharmony_ci			next = cast_expression(token->next, &unop);
717f08c3bdfSopenharmony_ci			if (!unop) {
718f08c3bdfSopenharmony_ci				sparse_error(token->pos, "Syntax error in unary expression");
719f08c3bdfSopenharmony_ci				*tree = NULL;
720f08c3bdfSopenharmony_ci				return next;
721f08c3bdfSopenharmony_ci			}
722f08c3bdfSopenharmony_ci			unary = alloc_expression(token->pos, EXPR_PREOP);
723f08c3bdfSopenharmony_ci			unary->op = token->special;
724f08c3bdfSopenharmony_ci			unary->unop = unop;
725f08c3bdfSopenharmony_ci			*tree = unary;
726f08c3bdfSopenharmony_ci			return next;
727f08c3bdfSopenharmony_ci		}
728f08c3bdfSopenharmony_ci		/* Gcc extension: &&label gives the address of a label */
729f08c3bdfSopenharmony_ci		if (match_op(token, SPECIAL_LOGICAL_AND) &&
730f08c3bdfSopenharmony_ci		    token_type(token->next) == TOKEN_IDENT) {
731f08c3bdfSopenharmony_ci			struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
732f08c3bdfSopenharmony_ci			struct symbol *sym = label_symbol(token->next, 1);
733f08c3bdfSopenharmony_ci			if (!(sym->ctype.modifiers & MOD_ADDRESSABLE)) {
734f08c3bdfSopenharmony_ci				sym->ctype.modifiers |= MOD_ADDRESSABLE;
735f08c3bdfSopenharmony_ci				add_symbol(&function_computed_target_list, sym);
736f08c3bdfSopenharmony_ci			}
737f08c3bdfSopenharmony_ci			check_label_usage(sym, token->pos);
738f08c3bdfSopenharmony_ci			label->flags = CEF_ADDR;
739f08c3bdfSopenharmony_ci			label->label_symbol = sym;
740f08c3bdfSopenharmony_ci			*tree = label;
741f08c3bdfSopenharmony_ci			return token->next->next;
742f08c3bdfSopenharmony_ci		}
743f08c3bdfSopenharmony_ci
744f08c3bdfSopenharmony_ci	}
745f08c3bdfSopenharmony_ci
746f08c3bdfSopenharmony_ci	return postfix_expression(token, tree, NULL);
747f08c3bdfSopenharmony_ci}
748f08c3bdfSopenharmony_ci
749f08c3bdfSopenharmony_ci/*
750f08c3bdfSopenharmony_ci * Ambiguity: a '(' can be either a cast-expression or
751f08c3bdfSopenharmony_ci * a primary-expression depending on whether it is followed
752f08c3bdfSopenharmony_ci * by a type or not.
753f08c3bdfSopenharmony_ci *
754f08c3bdfSopenharmony_ci * additional ambiguity: a "cast expression" followed by
755f08c3bdfSopenharmony_ci * an initializer is really a postfix-expression.
756f08c3bdfSopenharmony_ci */
757f08c3bdfSopenharmony_cistatic struct token *cast_expression(struct token *token, struct expression **tree)
758f08c3bdfSopenharmony_ci{
759f08c3bdfSopenharmony_ci	if (match_op(token, '(')) {
760f08c3bdfSopenharmony_ci		struct token *next = token->next;
761f08c3bdfSopenharmony_ci		if (lookup_type(next)) {
762f08c3bdfSopenharmony_ci			struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
763f08c3bdfSopenharmony_ci			struct expression *v;
764f08c3bdfSopenharmony_ci			struct symbol *sym;
765f08c3bdfSopenharmony_ci			int is_force;
766f08c3bdfSopenharmony_ci
767f08c3bdfSopenharmony_ci			token = typename(next, &sym, &is_force);
768f08c3bdfSopenharmony_ci			cast->cast_type = sym;
769f08c3bdfSopenharmony_ci			token = expect(token, ')', "at end of cast operator");
770f08c3bdfSopenharmony_ci			if (match_op(token, '{')) {
771f08c3bdfSopenharmony_ci				if (toplevel(block_scope))
772f08c3bdfSopenharmony_ci					sym->ctype.modifiers |= MOD_TOPLEVEL;
773f08c3bdfSopenharmony_ci				if (is_force)
774f08c3bdfSopenharmony_ci					warning(sym->pos,
775f08c3bdfSopenharmony_ci						"[force] in compound literal");
776f08c3bdfSopenharmony_ci				token = initializer(&cast->cast_expression, token);
777f08c3bdfSopenharmony_ci				return postfix_expression(token, tree, cast);
778f08c3bdfSopenharmony_ci			}
779f08c3bdfSopenharmony_ci			*tree = cast;
780f08c3bdfSopenharmony_ci			if (is_force)
781f08c3bdfSopenharmony_ci				cast->type = EXPR_FORCE_CAST;
782f08c3bdfSopenharmony_ci			token = cast_expression(token, &v);
783f08c3bdfSopenharmony_ci			if (!v)
784f08c3bdfSopenharmony_ci				return token;
785f08c3bdfSopenharmony_ci			cast->cast_expression = v;
786f08c3bdfSopenharmony_ci			return token;
787f08c3bdfSopenharmony_ci		}
788f08c3bdfSopenharmony_ci	}
789f08c3bdfSopenharmony_ci	return unary_expression(token, tree);
790f08c3bdfSopenharmony_ci}
791f08c3bdfSopenharmony_ci
792f08c3bdfSopenharmony_ci/*
793f08c3bdfSopenharmony_ci * Generic left-to-right binop parsing
794f08c3bdfSopenharmony_ci *
795f08c3bdfSopenharmony_ci * This _really_ needs to be inlined, because that makes the inner
796f08c3bdfSopenharmony_ci * function call statically deterministic rather than a totally
797f08c3bdfSopenharmony_ci * unpredictable indirect call. But gcc-3 is so "clever" that it
798f08c3bdfSopenharmony_ci * doesn't do so by default even when you tell it to inline it.
799f08c3bdfSopenharmony_ci *
800f08c3bdfSopenharmony_ci * Making it a macro avoids the inlining problem, and also means
801f08c3bdfSopenharmony_ci * that we can pass in the op-comparison as an expression rather
802f08c3bdfSopenharmony_ci * than create a data structure for it.
803f08c3bdfSopenharmony_ci */
804f08c3bdfSopenharmony_ci
805f08c3bdfSopenharmony_ci#define LR_BINOP_EXPRESSION(__token, tree, type, inner, compare)	\
806f08c3bdfSopenharmony_ci	struct expression *left = NULL;					\
807f08c3bdfSopenharmony_ci	struct token * next = inner(__token, &left);			\
808f08c3bdfSopenharmony_ci									\
809f08c3bdfSopenharmony_ci	if (left) {							\
810f08c3bdfSopenharmony_ci		while (token_type(next) == TOKEN_SPECIAL) {		\
811f08c3bdfSopenharmony_ci			struct expression *top, *right = NULL;		\
812f08c3bdfSopenharmony_ci			int op = next->special;				\
813f08c3bdfSopenharmony_ci									\
814f08c3bdfSopenharmony_ci			if (!(compare))					\
815f08c3bdfSopenharmony_ci				goto out;				\
816f08c3bdfSopenharmony_ci			top = alloc_expression(next->pos, type);	\
817f08c3bdfSopenharmony_ci			next = inner(next->next, &right);		\
818f08c3bdfSopenharmony_ci			if (!right) {					\
819f08c3bdfSopenharmony_ci				sparse_error(next->pos, "No right hand side of '%s'-expression", show_special(op));	\
820f08c3bdfSopenharmony_ci				break;					\
821f08c3bdfSopenharmony_ci			}						\
822f08c3bdfSopenharmony_ci			top->op = op;					\
823f08c3bdfSopenharmony_ci			top->left = left;				\
824f08c3bdfSopenharmony_ci			top->right = right;				\
825f08c3bdfSopenharmony_ci			left = top;					\
826f08c3bdfSopenharmony_ci		}							\
827f08c3bdfSopenharmony_ci	}								\
828f08c3bdfSopenharmony_ciout:									\
829f08c3bdfSopenharmony_ci	*tree = left;							\
830f08c3bdfSopenharmony_ci	return next;							\
831f08c3bdfSopenharmony_ci
832f08c3bdfSopenharmony_cistatic struct token *multiplicative_expression(struct token *token, struct expression **tree)
833f08c3bdfSopenharmony_ci{
834f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
835f08c3bdfSopenharmony_ci		token, tree, EXPR_BINOP, cast_expression,
836f08c3bdfSopenharmony_ci		(op == '*') || (op == '/') || (op == '%')
837f08c3bdfSopenharmony_ci	);
838f08c3bdfSopenharmony_ci}
839f08c3bdfSopenharmony_ci
840f08c3bdfSopenharmony_cistatic struct token *additive_expression(struct token *token, struct expression **tree)
841f08c3bdfSopenharmony_ci{
842f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
843f08c3bdfSopenharmony_ci		token, tree, EXPR_BINOP, multiplicative_expression,
844f08c3bdfSopenharmony_ci		(op == '+') || (op == '-')
845f08c3bdfSopenharmony_ci	);
846f08c3bdfSopenharmony_ci}
847f08c3bdfSopenharmony_ci
848f08c3bdfSopenharmony_cistatic struct token *shift_expression(struct token *token, struct expression **tree)
849f08c3bdfSopenharmony_ci{
850f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
851f08c3bdfSopenharmony_ci		token, tree, EXPR_BINOP, additive_expression,
852f08c3bdfSopenharmony_ci		(op == SPECIAL_LEFTSHIFT) || (op == SPECIAL_RIGHTSHIFT)
853f08c3bdfSopenharmony_ci	);
854f08c3bdfSopenharmony_ci}
855f08c3bdfSopenharmony_ci
856f08c3bdfSopenharmony_cistatic struct token *relational_expression(struct token *token, struct expression **tree)
857f08c3bdfSopenharmony_ci{
858f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
859f08c3bdfSopenharmony_ci		token, tree, EXPR_COMPARE, shift_expression,
860f08c3bdfSopenharmony_ci		(op == '<') || (op == '>') ||
861f08c3bdfSopenharmony_ci		(op == SPECIAL_LTE) || (op == SPECIAL_GTE)
862f08c3bdfSopenharmony_ci	);
863f08c3bdfSopenharmony_ci}
864f08c3bdfSopenharmony_ci
865f08c3bdfSopenharmony_cistatic struct token *equality_expression(struct token *token, struct expression **tree)
866f08c3bdfSopenharmony_ci{
867f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
868f08c3bdfSopenharmony_ci		token, tree, EXPR_COMPARE, relational_expression,
869f08c3bdfSopenharmony_ci		(op == SPECIAL_EQUAL) || (op == SPECIAL_NOTEQUAL)
870f08c3bdfSopenharmony_ci	);
871f08c3bdfSopenharmony_ci}
872f08c3bdfSopenharmony_ci
873f08c3bdfSopenharmony_cistatic struct token *bitwise_and_expression(struct token *token, struct expression **tree)
874f08c3bdfSopenharmony_ci{
875f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
876f08c3bdfSopenharmony_ci		token, tree, EXPR_BINOP, equality_expression,
877f08c3bdfSopenharmony_ci		(op == '&')
878f08c3bdfSopenharmony_ci	);
879f08c3bdfSopenharmony_ci}
880f08c3bdfSopenharmony_ci
881f08c3bdfSopenharmony_cistatic struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
882f08c3bdfSopenharmony_ci{
883f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
884f08c3bdfSopenharmony_ci		token, tree, EXPR_BINOP, bitwise_and_expression,
885f08c3bdfSopenharmony_ci		(op == '^')
886f08c3bdfSopenharmony_ci	);
887f08c3bdfSopenharmony_ci}
888f08c3bdfSopenharmony_ci
889f08c3bdfSopenharmony_cistatic struct token *bitwise_or_expression(struct token *token, struct expression **tree)
890f08c3bdfSopenharmony_ci{
891f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
892f08c3bdfSopenharmony_ci		token, tree, EXPR_BINOP, bitwise_xor_expression,
893f08c3bdfSopenharmony_ci		(op == '|')
894f08c3bdfSopenharmony_ci	);
895f08c3bdfSopenharmony_ci}
896f08c3bdfSopenharmony_ci
897f08c3bdfSopenharmony_cistatic struct token *logical_and_expression(struct token *token, struct expression **tree)
898f08c3bdfSopenharmony_ci{
899f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
900f08c3bdfSopenharmony_ci		token, tree, EXPR_LOGICAL, bitwise_or_expression,
901f08c3bdfSopenharmony_ci		(op == SPECIAL_LOGICAL_AND)
902f08c3bdfSopenharmony_ci	);
903f08c3bdfSopenharmony_ci}
904f08c3bdfSopenharmony_ci
905f08c3bdfSopenharmony_cistatic struct token *logical_or_expression(struct token *token, struct expression **tree)
906f08c3bdfSopenharmony_ci{
907f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
908f08c3bdfSopenharmony_ci		token, tree, EXPR_LOGICAL, logical_and_expression,
909f08c3bdfSopenharmony_ci		(op == SPECIAL_LOGICAL_OR)
910f08c3bdfSopenharmony_ci	);
911f08c3bdfSopenharmony_ci}
912f08c3bdfSopenharmony_ci
913f08c3bdfSopenharmony_cistruct token *conditional_expression(struct token *token, struct expression **tree)
914f08c3bdfSopenharmony_ci{
915f08c3bdfSopenharmony_ci	token = logical_or_expression(token, tree);
916f08c3bdfSopenharmony_ci	if (*tree && match_op(token, '?')) {
917f08c3bdfSopenharmony_ci		struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
918f08c3bdfSopenharmony_ci		expr->op = token->special;
919f08c3bdfSopenharmony_ci		expr->conditional = *tree;
920f08c3bdfSopenharmony_ci		*tree = expr;
921f08c3bdfSopenharmony_ci		token = parse_expression(token->next, &expr->cond_true);
922f08c3bdfSopenharmony_ci		token = expect(token, ':', "in conditional expression");
923f08c3bdfSopenharmony_ci		token = conditional_expression(token, &expr->cond_false);
924f08c3bdfSopenharmony_ci	}
925f08c3bdfSopenharmony_ci	return token;
926f08c3bdfSopenharmony_ci}
927f08c3bdfSopenharmony_ci
928f08c3bdfSopenharmony_cistruct token *assignment_expression(struct token *token, struct expression **tree)
929f08c3bdfSopenharmony_ci{
930f08c3bdfSopenharmony_ci	token = conditional_expression(token, tree);
931f08c3bdfSopenharmony_ci	if (*tree && token_type(token) == TOKEN_SPECIAL) {
932f08c3bdfSopenharmony_ci		static const int assignments[] = {
933f08c3bdfSopenharmony_ci			'=',
934f08c3bdfSopenharmony_ci			SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN,
935f08c3bdfSopenharmony_ci			SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN,
936f08c3bdfSopenharmony_ci			SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN,
937f08c3bdfSopenharmony_ci			SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN,
938f08c3bdfSopenharmony_ci			SPECIAL_OR_ASSIGN,  SPECIAL_XOR_ASSIGN };
939f08c3bdfSopenharmony_ci		int i, op = token->special;
940f08c3bdfSopenharmony_ci		for (i = 0; i < ARRAY_SIZE(assignments); i++)
941f08c3bdfSopenharmony_ci			if (assignments[i] == op) {
942f08c3bdfSopenharmony_ci				struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
943f08c3bdfSopenharmony_ci				struct token *next = token->next;
944f08c3bdfSopenharmony_ci				expr->left = *tree;
945f08c3bdfSopenharmony_ci				expr->op = op;
946f08c3bdfSopenharmony_ci				*tree = expr;
947f08c3bdfSopenharmony_ci				token = assignment_expression(next, &expr->right);
948f08c3bdfSopenharmony_ci				if (token == next)
949f08c3bdfSopenharmony_ci					expression_error(expr, "expression expected before '%s'", show_token(token));
950f08c3bdfSopenharmony_ci				return token;
951f08c3bdfSopenharmony_ci			}
952f08c3bdfSopenharmony_ci	}
953f08c3bdfSopenharmony_ci	return token;
954f08c3bdfSopenharmony_ci}
955f08c3bdfSopenharmony_ci
956f08c3bdfSopenharmony_cistatic struct token *comma_expression(struct token *token, struct expression **tree)
957f08c3bdfSopenharmony_ci{
958f08c3bdfSopenharmony_ci	LR_BINOP_EXPRESSION(
959f08c3bdfSopenharmony_ci		token, tree, EXPR_COMMA, assignment_expression,
960f08c3bdfSopenharmony_ci		(op == ',')
961f08c3bdfSopenharmony_ci	);
962f08c3bdfSopenharmony_ci}
963f08c3bdfSopenharmony_ci
964f08c3bdfSopenharmony_cistruct token *parse_expression(struct token *token, struct expression **tree)
965f08c3bdfSopenharmony_ci{
966f08c3bdfSopenharmony_ci	return comma_expression(token,tree);
967f08c3bdfSopenharmony_ci}
968f08c3bdfSopenharmony_ci
969f08c3bdfSopenharmony_ci
970