1#ifndef EXPRESSION_H
2#define EXPRESSION_H
3/*
4 * sparse/expression.h
5 *
6 * Copyright (C) 2003 Transmeta Corp.
7 *               2003 Linus Torvalds
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 *
27 * Declarations and helper functions for expression parsing.
28 */
29
30#include "allocate.h"
31#include "lib.h"
32#include "symbol.h"
33
34struct expression_list;
35
36enum expression_type {
37	EXPR_VALUE = 1,
38	EXPR_STRING,
39	EXPR_SYMBOL,
40	EXPR_TYPE,
41	EXPR_BINOP,
42	EXPR_ASSIGNMENT,
43	EXPR_LOGICAL,
44	EXPR_DEREF,
45	EXPR_PREOP,
46	EXPR_POSTOP,
47	EXPR_CAST,
48	EXPR_FORCE_CAST,
49	EXPR_IMPLIED_CAST,
50	EXPR_SIZEOF,
51	EXPR_ALIGNOF,
52	EXPR_PTRSIZEOF,
53	EXPR_CONDITIONAL,
54	EXPR_SELECT,		// a "safe" conditional expression
55	EXPR_STATEMENT,
56	EXPR_CALL,
57	EXPR_COMMA,
58	EXPR_COMPARE,
59	EXPR_LABEL,
60	EXPR_INITIALIZER,	// initializer list
61	EXPR_IDENTIFIER,	// identifier in initializer
62	EXPR_INDEX,		// index in initializer
63	EXPR_POS,		// position in initializer
64	EXPR_FVALUE,
65	EXPR_SLICE,
66	EXPR_OFFSETOF,
67	EXPR_GENERIC,
68};
69
70
71/*
72 * Flags for tracking the promotion of constness related attributes
73 * from subexpressions to their parents.
74 *
75 * The flags are not independent as one might imply another.
76 * The implications are as follows:
77 * - CEF_INT, CEF_ENUM and
78 *   CEF_CHAR imply CEF_ICE.
79 *
80 * Use the CEF_*_SET_MASK and CEF_*_CLEAR_MASK
81 * helper macros defined below to set or clear one of these flags.
82 */
83enum constexpr_flag {
84	CEF_NONE = 0,
85	/*
86	 * A constant in the sense of [6.4.4]:
87	 * - Integer constant [6.4.4.1]
88	 * - Floating point constant [6.4.4.2]
89	 * - Enumeration constant [6.4.4.3]
90	 * - Character constant [6.4.4.4]
91	 */
92	CEF_INT = (1 << 0),
93	CEF_FLOAT = (1 << 1),
94	CEF_ENUM = (1 << 2),
95	CEF_CHAR = (1 << 3),
96
97	/*
98	 * A constant expression in the sense of [6.6]:
99	 * - integer constant expression [6.6(6)]
100	 * - arithmetic constant expression [6.6(8)]
101	 * - address constant [6.6(9)]
102	 */
103	CEF_ICE = (1 << 4),
104	CEF_ACE = (1 << 5),
105	CEF_ADDR = (1 << 6),
106
107	/* integer constant expression => arithmetic constant expression */
108	CEF_SET_ICE = (CEF_ICE | CEF_ACE),
109
110	/* integer constant => integer constant expression */
111	CEF_SET_INT = (CEF_INT | CEF_SET_ICE),
112
113	/* floating point constant => arithmetic constant expression */
114	CEF_SET_FLOAT = (CEF_FLOAT | CEF_ACE),
115
116	/* enumeration constant => integer constant expression */
117	CEF_SET_ENUM = (CEF_ENUM | CEF_SET_ICE),
118
119	/* character constant => integer constant expression */
120	CEF_SET_CHAR = (CEF_CHAR | CEF_SET_ICE),
121
122	/*
123	 * Remove any "Constant" [6.4.4] flag, but retain the "constant
124	 * expression" [6.6] flags.
125	 */
126	CEF_CONST_MASK = (CEF_INT | CEF_FLOAT | CEF_CHAR),
127
128	/*
129	 * not an integer constant expression => neither of integer,
130	 * enumeration and character constant
131	 */
132	CEF_CLR_ICE = (CEF_ICE | CEF_INT | CEF_ENUM | CEF_CHAR),
133};
134
135enum {
136	Taint_comma = 1,
137}; /* for expr->taint */
138
139struct asm_operand {
140	struct ident *name;
141	struct expression *constraint;
142	struct expression *expr;
143	unsigned int is_assign:1;
144	unsigned int is_modify:1;
145	unsigned int is_earlyclobber:1;
146	unsigned int is_commutative:1;
147	unsigned int is_register:1;
148	unsigned int is_memory:1;
149};
150
151struct type_expression {
152	struct symbol *type;
153	struct expression *expr;
154	struct type_expression *next;
155};
156
157DECLARE_ALLOCATOR(type_expression);
158
159struct expression {
160	enum expression_type type:8;
161	unsigned flags:8;
162	unsigned zero_init:1;
163	int op;
164	struct position pos;
165	struct symbol *ctype;
166	union {
167		// EXPR_VALUE
168		struct {
169			unsigned long long value;
170			unsigned taint;
171		};
172
173		// EXPR_FVALUE
174		long double fvalue;
175
176		// EXPR_STRING
177		struct {
178			int wide;
179			struct string *string;
180		};
181
182		// EXPR_UNOP, EXPR_PREOP and EXPR_POSTOP
183		struct /* unop */ {
184			struct expression *unop;
185			unsigned long op_value;
186		};
187
188		// EXPR_SYMBOL, EXPR_TYPE
189		struct /* symbol_arg */ {
190			struct symbol *symbol;
191			struct ident *symbol_name;
192		};
193
194		// EXPR_STATEMENT
195		struct statement *statement;
196
197		// EXPR_BINOP, EXPR_COMMA, EXPR_COMPARE, EXPR_LOGICAL and EXPR_ASSIGNMENT
198		struct /* binop_arg */ {
199			struct expression *left, *right;
200		};
201		// EXPR_DEREF
202		struct /* deref_arg */ {
203			struct expression *deref;
204			struct ident *member;
205		};
206		// EXPR_SLICE
207		struct /* slice */ {
208			struct expression *base;
209			unsigned r_bitpos;
210		};
211		// EXPR_CAST, EXPR_FORCE_CAST, EXPR_IMPLIED_CAST,
212		// EXPR_SIZEOF, EXPR_ALIGNOF and EXPR_PTRSIZEOF
213		struct /* cast_arg */ {
214			struct symbol *cast_type;
215			struct expression *cast_expression;
216		};
217		// EXPR_CONDITIONAL
218		// EXPR_SELECT
219		struct /* conditional_expr */ {
220			struct expression *conditional, *cond_true, *cond_false;
221		};
222		// EXPR_CALL
223		struct /* call_expr */ {
224			struct expression *fn;
225			struct expression_list *args;
226		};
227		// EXPR_LABEL
228		struct /* label_expr */ {
229			struct symbol *label_symbol;
230		};
231		// EXPR_INITIALIZER
232		struct expression_list *expr_list;
233		// EXPR_IDENTIFIER
234		struct /* ident_expr */ {
235			int offset;
236			struct ident *expr_ident;
237			struct symbol *field;
238			struct expression *ident_expression;
239		};
240		// EXPR_INDEX
241		struct /* index_expr */ {
242			unsigned int idx_from, idx_to;
243			struct expression *idx_expression;
244		};
245		// EXPR_POS
246		struct /* initpos_expr */ {
247			unsigned int init_offset, init_nr;
248			struct expression *init_expr;
249		};
250		// EXPR_OFFSETOF
251		struct {
252			struct symbol *in;
253			struct expression *down;
254			union {
255				struct ident *ident;
256				struct expression *index;
257			};
258		};
259		// EXPR_GENERIC
260		struct {
261			struct expression *control;
262			struct expression *def;
263			struct type_expression *map;
264		};
265	};
266};
267
268///
269// Constant expression values
270// --------------------------
271
272///
273// test if an expression evaluates to the constant ``0``.
274// @return: ``1`` if @expr evaluate to ``0``,
275//	``0`` otherwise.
276int is_zero_constant(struct expression *expr);
277
278///
279// test the compile time truth value of an expression
280// @return:
281//	* ``-1`` if @expr is not constant,
282//	* ``0`` or ``1`` depending on the truth value of @expr.
283int expr_truth_value(struct expression *expr);
284
285long long get_expression_value(struct expression *);
286long long const_expression_value(struct expression *);
287long long get_expression_value_silent(struct expression *expr);
288
289/* Expression parsing */
290struct token *parse_expression(struct token *token, struct expression **tree);
291struct token *conditional_expression(struct token *token, struct expression **tree);
292struct token *primary_expression(struct token *token, struct expression **tree);
293struct token *parens_expression(struct token *token, struct expression **expr, const char *where);
294struct token *string_expression(struct token *token, struct expression **expr, const char *where);
295struct token *assignment_expression(struct token *token, struct expression **tree);
296
297extern int expand_symbol(struct symbol *);
298
299static inline struct expression *alloc_expression(struct position pos, int type)
300{
301	struct expression *expr = __alloc_expression(0);
302	expr->type = type;
303	expr->pos = pos;
304	expr->flags = CEF_NONE;
305	return expr;
306}
307
308static inline struct expression *alloc_const_expression(struct position pos, int value)
309{
310	struct expression *expr = __alloc_expression(0);
311	expr->type = EXPR_VALUE;
312	expr->pos = pos;
313	expr->value = value;
314	expr->ctype = &int_ctype;
315	expr->flags = CEF_SET_INT;
316	return expr;
317}
318
319/* Type name parsing */
320struct token *typename(struct token *, struct symbol **, int *);
321
322static inline int lookup_type(struct token *token)
323{
324	if (token->pos.type == TOKEN_IDENT) {
325		struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
326		return sym && (sym->namespace & NS_TYPEDEF);
327	}
328	return 0;
329}
330
331/* Statement parsing */
332struct statement *alloc_statement(struct position pos, int type);
333struct token *initializer(struct expression **tree, struct token *token);
334struct token *compound_statement(struct token *, struct statement *);
335
336/* The preprocessor calls this 'constant_expression()' */
337#define constant_expression(token,tree) conditional_expression(token, tree)
338
339/* Cast folding of constant values.. */
340void cast_value(struct expression *expr, struct symbol *newtype,
341	struct expression *old, struct symbol *oldtype);
342
343#endif
344