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