| #ifndef EXPRESSION_H | 
 | #define EXPRESSION_H | 
 | /* | 
 |  * sparse/expression.h | 
 |  * | 
 |  * Copyright (C) 2003 Transmeta Corp. | 
 |  *               2003 Linus Torvalds | 
 |  * | 
 |  *  Licensed under the Open Software License version 1.1 | 
 |  * | 
 |  * Declarations and helper functions for expression parsing. | 
 |  */ | 
 |  | 
 | #include "allocate.h" | 
 | #include "lib.h" | 
 | #include "symbol.h" | 
 |  | 
 | struct expression_list; | 
 |  | 
 | enum expression_type { | 
 | 	EXPR_VALUE = 1, | 
 | 	EXPR_STRING, | 
 | 	EXPR_SYMBOL, | 
 | 	EXPR_TYPE, | 
 | 	EXPR_BINOP, | 
 | 	EXPR_ASSIGNMENT, | 
 | 	EXPR_LOGICAL, | 
 | 	EXPR_DEREF, | 
 | 	EXPR_PREOP, | 
 | 	EXPR_POSTOP, | 
 | 	EXPR_CAST, | 
 | 	EXPR_FORCE_CAST, | 
 | 	EXPR_IMPLIED_CAST, | 
 | 	EXPR_SIZEOF, | 
 | 	EXPR_ALIGNOF, | 
 | 	EXPR_PTRSIZEOF, | 
 | 	EXPR_CONDITIONAL, | 
 | 	EXPR_SELECT,		// a "safe" conditional expression | 
 | 	EXPR_STATEMENT, | 
 | 	EXPR_CALL, | 
 | 	EXPR_COMMA, | 
 | 	EXPR_COMPARE, | 
 | 	EXPR_LABEL, | 
 | 	EXPR_INITIALIZER,	// initializer list | 
 | 	EXPR_IDENTIFIER,	// identifier in initializer | 
 | 	EXPR_INDEX,		// index in initializer | 
 | 	EXPR_POS,		// position in initializer | 
 | 	EXPR_FVALUE, | 
 | 	EXPR_SLICE, | 
 | 	EXPR_OFFSETOF, | 
 | }; | 
 |  | 
 | enum { | 
 | 	Int_const_expr = 1, | 
 | 	Float_literal = 2, | 
 | }; /* for expr->flags */ | 
 |  | 
 | enum { | 
 | 	Taint_comma = 1, | 
 | }; /* for expr->taint */ | 
 |  | 
 | struct expression { | 
 | 	enum expression_type type:8; | 
 | 	unsigned flags:8; | 
 | 	int op; | 
 | 	struct position pos; | 
 | 	struct symbol *ctype; | 
 | 	union { | 
 | 		// EXPR_VALUE | 
 | 		struct { | 
 | 			unsigned long long value; | 
 | 			unsigned taint; | 
 | 		}; | 
 |  | 
 | 		// EXPR_FVALUE | 
 | 		long double fvalue; | 
 |  | 
 | 		// EXPR_STRING | 
 | 		struct { | 
 | 			int wide; | 
 | 			struct string *string; | 
 | 		}; | 
 |  | 
 | 		// EXPR_UNOP, EXPR_PREOP and EXPR_POSTOP | 
 | 		struct /* unop */ { | 
 | 			struct expression *unop; | 
 | 			unsigned long op_value; | 
 | 		}; | 
 |  | 
 | 		// EXPR_SYMBOL, EXPR_TYPE | 
 | 		struct /* symbol_arg */ { | 
 | 			struct symbol *symbol; | 
 | 			struct ident *symbol_name; | 
 | 		}; | 
 |  | 
 | 		// EXPR_STATEMENT | 
 | 		struct statement *statement; | 
 |  | 
 | 		// EXPR_BINOP, EXPR_COMMA, EXPR_COMPARE, EXPR_LOGICAL and EXPR_ASSIGNMENT | 
 | 		struct /* binop_arg */ { | 
 | 			struct expression *left, *right; | 
 | 		}; | 
 | 		// EXPR_DEREF | 
 | 		struct /* deref_arg */ { | 
 | 			struct expression *deref; | 
 | 			struct ident *member; | 
 | 		}; | 
 | 		// EXPR_SLICE | 
 | 		struct /* slice */ { | 
 | 			struct expression *base; | 
 | 			unsigned r_bitpos, r_nrbits; | 
 | 		}; | 
 | 		// EXPR_CAST and EXPR_SIZEOF | 
 | 		struct /* cast_arg */ { | 
 | 			struct symbol *cast_type; | 
 | 			struct expression *cast_expression; | 
 | 		}; | 
 | 		// EXPR_CONDITIONAL | 
 | 		// EXPR_SELECT | 
 | 		struct /* conditional_expr */ { | 
 | 			struct expression *conditional, *cond_true, *cond_false; | 
 | 		}; | 
 | 		// EXPR_CALL | 
 | 		struct /* call_expr */ { | 
 | 			struct expression *fn; | 
 | 			struct expression_list *args; | 
 | 		}; | 
 | 		// EXPR_LABEL | 
 | 		struct /* label_expr */ { | 
 | 			struct symbol *label_symbol; | 
 | 		}; | 
 | 		// EXPR_INITIALIZER | 
 | 		struct expression_list *expr_list; | 
 | 		// EXPR_IDENTIFIER | 
 | 		struct /* ident_expr */ { | 
 | 			struct ident *expr_ident; | 
 | 			struct symbol *field; | 
 | 			struct expression *ident_expression; | 
 | 		}; | 
 | 		// EXPR_INDEX | 
 | 		struct /* index_expr */ { | 
 | 			unsigned int idx_from, idx_to; | 
 | 			struct expression *idx_expression; | 
 | 		}; | 
 | 		// EXPR_POS | 
 | 		struct /* initpos_expr */ { | 
 | 			unsigned int init_offset, init_nr; | 
 | 			struct expression *init_expr; | 
 | 		}; | 
 | 		// EXPR_OFFSETOF | 
 | 		struct { | 
 | 			struct symbol *in; | 
 | 			struct expression *down; | 
 | 			union { | 
 | 				struct ident *ident; | 
 | 				struct expression *index; | 
 | 			}; | 
 | 		}; | 
 | 	}; | 
 | }; | 
 |  | 
 | /* Constant expression values */ | 
 | int is_zero_constant(struct expression *); | 
 | long long get_expression_value(struct expression *); | 
 | long long const_expression_value(struct expression *); | 
 |  | 
 | /* Expression parsing */ | 
 | struct token *parse_expression(struct token *token, struct expression **tree); | 
 | struct token *conditional_expression(struct token *token, struct expression **tree); | 
 | struct token *primary_expression(struct token *token, struct expression **tree); | 
 | struct token *parens_expression(struct token *token, struct expression **expr, const char *where); | 
 | struct token *assignment_expression(struct token *token, struct expression **tree); | 
 |  | 
 | extern void evaluate_symbol_list(struct symbol_list *list); | 
 | extern struct symbol *evaluate_statement(struct statement *stmt); | 
 | extern struct symbol *evaluate_expression(struct expression *); | 
 |  | 
 | extern int expand_symbol(struct symbol *); | 
 |  | 
 | static inline struct expression *alloc_expression(struct position pos, int type) | 
 | { | 
 | 	struct expression *expr = __alloc_expression(0); | 
 | 	expr->type = type; | 
 | 	expr->pos = pos; | 
 | 	return expr; | 
 | } | 
 |  | 
 | static inline struct expression *alloc_const_expression(struct position pos, int value) | 
 | { | 
 | 	struct expression *expr = __alloc_expression(0); | 
 | 	expr->type = EXPR_VALUE; | 
 | 	expr->pos = pos; | 
 | 	expr->value = value; | 
 | 	expr->ctype = &int_ctype; | 
 | 	return expr; | 
 | } | 
 |  | 
 | /* Type name parsing */ | 
 | struct token *typename(struct token *, struct symbol **, int *); | 
 |  | 
 | static inline int lookup_type(struct token *token) | 
 | { | 
 | 	if (token->pos.type == TOKEN_IDENT) { | 
 | 		struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF); | 
 | 		return sym && (sym->namespace & NS_TYPEDEF); | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 | /* Statement parsing */ | 
 | struct statement *alloc_statement(struct position pos, int type); | 
 | struct token *initializer(struct expression **tree, struct token *token); | 
 | struct token *compound_statement(struct token *, struct statement *); | 
 |  | 
 | /* The preprocessor calls this 'constant_expression()' */ | 
 | #define constant_expression(token,tree) conditional_expression(token, tree) | 
 |  | 
 | /* Cast folding of constant values.. */ | 
 | void cast_value(struct expression *expr, struct symbol *newtype, | 
 | 	struct expression *old, struct symbol *oldtype); | 
 |  | 
 | #endif |