/*
 * sparse/expand.c
 *
 * Copyright (C) 2003 Transmeta Corp.
 *               2003-2004 Linus Torvalds
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * expand constant expressions.
 */
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>

#include "lib.h"
#include "allocate.h"
#include "parse.h"
#include "token.h"
#include "symbol.h"
#include "target.h"
#include "expression.h"

/* Random cost numbers */
#define SIDE_EFFECTS 10000	/* The expression has side effects */
#define UNSAFE 100		/* The expression may be "infinitely costly" due to exceptions */
#define SELECT_COST 20		/* Cut-off for turning a conditional into a select */
#define BRANCH_COST 10		/* Cost of a conditional branch */

static int expand_expression(struct expression *);
static int expand_statement(struct statement *);
static int conservative;

static int expand_symbol_expression(struct expression *expr)
{
	struct symbol *sym = expr->symbol;

	if (sym == &zero_int) {
		if (Wundef)
			warning(expr->pos, "undefined preprocessor identifier '%s'", show_ident(expr->symbol_name));
		expr->type = EXPR_VALUE;
		expr->value = 0;
		expr->taint = 0;
		return 0;
	}
	/* The cost of a symbol expression is lower for on-stack symbols */
	return (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN)) ? 2 : 1;
}

static long long get_longlong(struct expression *expr)
{
	int no_expand = expr->ctype->ctype.modifiers & MOD_UNSIGNED;
	long long mask = 1ULL << (expr->ctype->bit_size - 1);
	long long value = expr->value;
	long long ormask, andmask;

	if (!(value & mask))
		no_expand = 1;
	andmask = mask | (mask-1);
	ormask = ~andmask;
	if (no_expand)
		ormask = 0;
	return (value & andmask) | ormask;
}

void cast_value(struct expression *expr, struct symbol *newtype,
		struct expression *old, struct symbol *oldtype)
{
	int old_size = oldtype->bit_size;
	int new_size = newtype->bit_size;
	long long value, mask, signmask;
	long long oldmask, oldsignmask, dropped;

	if (newtype->ctype.base_type == &fp_type ||
	    oldtype->ctype.base_type == &fp_type)
		goto Float;

	// For pointers and integers, we can just move the value around
	expr->type = EXPR_VALUE;
	expr->taint = old->taint;
	if (old_size == new_size) {
		expr->value = old->value;
		return;
	}

	// expand it to the full "long long" value
	value = get_longlong(old);

Int:
	// _Bool requires a zero test rather than truncation.
	if (is_bool_type(newtype)) {
		expr->value = !!value;
		if (!conservative && value != 0 && value != 1)
			warning(old->pos, "odd constant _Bool cast (%llx becomes 1)", value);
		return;
	}

	// Truncate it to the new size
	signmask = 1ULL << (new_size-1);
	mask = signmask | (signmask-1);
	expr->value = value & mask;

	// Stop here unless checking for truncation
	if (!Wcast_truncate || conservative)
		return;
	
	// Check if we dropped any bits..
	oldsignmask = 1ULL << (old_size-1);
	oldmask = oldsignmask | (oldsignmask-1);
	dropped = oldmask & ~mask;

	// OK if the bits were (and still are) purely sign bits
	if (value & dropped) {
		if (!(value & oldsignmask) || !(value & signmask) || (value & dropped) != dropped)
			warning(old->pos, "cast truncates bits from constant value (%llx becomes %llx)",
				value & oldmask,
				value & mask);
	}
	return;

Float:
	if (!is_float_type(newtype)) {
		value = (long long)old->fvalue;
		expr->type = EXPR_VALUE;
		expr->taint = 0;
		goto Int;
	}

	if (!is_float_type(oldtype))
		expr->fvalue = (long double)get_longlong(old);
	else
		expr->fvalue = old->fvalue;

	if (!(newtype->ctype.modifiers & MOD_LONGLONG) && \
	    !(newtype->ctype.modifiers & MOD_LONGLONGLONG)) {
		if ((newtype->ctype.modifiers & MOD_LONG))
			expr->fvalue = (double)expr->fvalue;
		else
			expr->fvalue = (float)expr->fvalue;
	}
	expr->type = EXPR_FVALUE;
}

static int check_shift_count(struct expression *expr, struct symbol *ctype, unsigned int count)
{
	warning(expr->pos, "shift too big (%u) for type %s", count, show_typename(ctype));
	count &= ctype->bit_size-1;
	return count;
}

/*
 * CAREFUL! We need to get the size and sign of the
 * result right!
 */
#define CONVERT(op,s)	(((op)<<1)+(s))
#define SIGNED(op)	CONVERT(op, 1)
#define UNSIGNED(op)	CONVERT(op, 0)
static int simplify_int_binop(struct expression *expr, struct symbol *ctype)
{
	struct expression *left = expr->left, *right = expr->right;
	unsigned long long v, l, r, mask;
	signed long long sl, sr;
	int is_signed;

	if (right->type != EXPR_VALUE)
		return 0;
	r = right->value;
	if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) {
		if (r >= ctype->bit_size) {
			if (conservative)
				return 0;
			r = check_shift_count(expr, ctype, r);
			right->value = r;
		}
	}
	if (left->type != EXPR_VALUE)
		return 0;
	l = left->value; r = right->value;
	is_signed = !(ctype->ctype.modifiers & MOD_UNSIGNED);
	mask = 1ULL << (ctype->bit_size-1);
	sl = l; sr = r;
	if (is_signed && (sl & mask))
		sl |= ~(mask-1);
	if (is_signed && (sr & mask))
		sr |= ~(mask-1);
	
	switch (CONVERT(expr->op,is_signed)) {
	case SIGNED('+'):
	case UNSIGNED('+'):
		v = l + r;
		break;

	case SIGNED('-'):
	case UNSIGNED('-'):
		v = l - r;
		break;

	case SIGNED('&'):
	case UNSIGNED('&'):
		v = l & r;
		break;

	case SIGNED('|'):
	case UNSIGNED('|'):
		v = l | r;
		break;

	case SIGNED('^'):
	case UNSIGNED('^'):
		v = l ^ r;
		break;

	case SIGNED('*'):
		v = sl * sr;
		break;

	case UNSIGNED('*'):
		v = l * r;
		break;

	case SIGNED('/'):
		if (!r)
			goto Div;
		if (l == mask && sr == -1)
			goto Overflow;
		v = sl / sr;
		break;

	case UNSIGNED('/'):
		if (!r) goto Div;
		v = l / r; 
		break;

	case SIGNED('%'):
		if (!r)
			goto Div;
		if (l == mask && sr == -1)
			goto Overflow;
		v = sl % sr;
		break;

	case UNSIGNED('%'):
		if (!r) goto Div;
		v = l % r;
		break;

	case SIGNED(SPECIAL_LEFTSHIFT):
	case UNSIGNED(SPECIAL_LEFTSHIFT):
		v = l << r;
		break; 

	case SIGNED(SPECIAL_RIGHTSHIFT):
		v = sl >> r;
		break;

	case UNSIGNED(SPECIAL_RIGHTSHIFT):
		v = l >> r;
		break;

	default:
		return 0;
	}
	mask = mask | (mask-1);
	expr->value = v & mask;
	expr->type = EXPR_VALUE;
	expr->taint = left->taint | right->taint;
	return 1;
Div:
	if (!conservative)
		warning(expr->pos, "division by zero");
	return 0;
Overflow:
	if (!conservative)
		warning(expr->pos, "constant integer operation overflow");
	return 0;
}

static int simplify_cmp_binop(struct expression *expr, struct symbol *ctype)
{
	struct expression *left = expr->left, *right = expr->right;
	unsigned long long l, r, mask;
	signed long long sl, sr;

	if (left->type != EXPR_VALUE || right->type != EXPR_VALUE)
		return 0;
	l = left->value; r = right->value;
	mask = 1ULL << (ctype->bit_size-1);
	sl = l; sr = r;
	if (sl & mask)
		sl |= ~(mask-1);
	if (sr & mask)
		sr |= ~(mask-1);
	switch (expr->op) {
	case '<':		expr->value = sl < sr; break;
	case '>':		expr->value = sl > sr; break;
	case SPECIAL_LTE:	expr->value = sl <= sr; break;
	case SPECIAL_GTE:	expr->value = sl >= sr; break;
	case SPECIAL_EQUAL:	expr->value = l == r; break;
	case SPECIAL_NOTEQUAL:	expr->value = l != r; break;
	case SPECIAL_UNSIGNED_LT:expr->value = l < r; break;
	case SPECIAL_UNSIGNED_GT:expr->value = l > r; break;
	case SPECIAL_UNSIGNED_LTE:expr->value = l <= r; break;
	case SPECIAL_UNSIGNED_GTE:expr->value = l >= r; break;
	}
	expr->type = EXPR_VALUE;
	expr->taint = left->taint | right->taint;
	return 1;
}

static int simplify_float_binop(struct expression *expr)
{
	struct expression *left = expr->left, *right = expr->right;
	unsigned long mod = expr->ctype->ctype.modifiers;
	long double l, r, res;

	if (left->type != EXPR_FVALUE || right->type != EXPR_FVALUE)
		return 0;

	l = left->fvalue;
	r = right->fvalue;

	if (mod & MOD_LONGLONG) {
		switch (expr->op) {
		case '+':	res = l + r; break;
		case '-':	res = l - r; break;
		case '*':	res = l * r; break;
		case '/':	if (!r) goto Div;
				res = l / r; break;
		default: return 0;
		}
	} else if (mod & MOD_LONG) {
		switch (expr->op) {
		case '+':	res = (double) l + (double) r; break;
		case '-':	res = (double) l - (double) r; break;
		case '*':	res = (double) l * (double) r; break;
		case '/':	if (!r) goto Div;
				res = (double) l / (double) r; break;
		default: return 0;
		}
	} else {
		switch (expr->op) {
		case '+':	res = (float)l + (float)r; break;
		case '-':	res = (float)l - (float)r; break;
		case '*':	res = (float)l * (float)r; break;
		case '/':	if (!r) goto Div;
				res = (float)l / (float)r; break;
		default: return 0;
		}
	}
	expr->type = EXPR_FVALUE;
	expr->fvalue = res;
	return 1;
Div:
	if (!conservative)
		warning(expr->pos, "division by zero");
	return 0;
}

static int simplify_float_cmp(struct expression *expr, struct symbol *ctype)
{
	struct expression *left = expr->left, *right = expr->right;
	long double l, r;

	if (left->type != EXPR_FVALUE || right->type != EXPR_FVALUE)
		return 0;

	l = left->fvalue;
	r = right->fvalue;
	switch (expr->op) {
	case '<':		expr->value = l < r; break;
	case '>':		expr->value = l > r; break;
	case SPECIAL_LTE:	expr->value = l <= r; break;
	case SPECIAL_GTE:	expr->value = l >= r; break;
	case SPECIAL_EQUAL:	expr->value = l == r; break;
	case SPECIAL_NOTEQUAL:	expr->value = l != r; break;
	}
	expr->type = EXPR_VALUE;
	expr->taint = 0;
	return 1;
}

static int expand_binop(struct expression *expr)
{
	int cost;

	cost = expand_expression(expr->left);
	cost += expand_expression(expr->right);
	if (simplify_int_binop(expr, expr->ctype))
		return 0;
	if (simplify_float_binop(expr))
		return 0;
	return cost + 1;
}

static int expand_logical(struct expression *expr)
{
	struct expression *left = expr->left;
	struct expression *right;
	int cost, rcost;

	/* Do immediate short-circuiting ... */
	cost = expand_expression(left);
	if (left->type == EXPR_VALUE) {
		if (expr->op == SPECIAL_LOGICAL_AND) {
			if (!left->value) {
				expr->type = EXPR_VALUE;
				expr->value = 0;
				expr->taint = left->taint;
				return 0;
			}
		} else {
			if (left->value) {
				expr->type = EXPR_VALUE;
				expr->value = 1;
				expr->taint = left->taint;
				return 0;
			}
		}
	}

	right = expr->right;
	rcost = expand_expression(right);
	if (left->type == EXPR_VALUE && right->type == EXPR_VALUE) {
		/*
		 * We know the left value doesn't matter, since
		 * otherwise we would have short-circuited it..
		 */
		expr->type = EXPR_VALUE;
		expr->value = right->value != 0;
		expr->taint = left->taint | right->taint;
		return 0;
	}

	/*
	 * If the right side is safe and cheaper than a branch,
	 * just avoid the branch and turn it into a regular binop
	 * style SAFELOGICAL.
	 */
	if (rcost < BRANCH_COST) {
		expr->type = EXPR_BINOP;
		rcost -= BRANCH_COST - 1;
	}

	return cost + BRANCH_COST + rcost;
}

static int expand_comma(struct expression *expr)
{
	int cost;

	cost = expand_expression(expr->left);
	cost += expand_expression(expr->right);
	if (expr->left->type == EXPR_VALUE || expr->left->type == EXPR_FVALUE) {
		unsigned flags = expr->flags;
		unsigned taint;
		taint = expr->left->type == EXPR_VALUE ? expr->left->taint : 0;
		*expr = *expr->right;
		expr->flags = flags;
		if (expr->type == EXPR_VALUE)
			expr->taint |= Taint_comma | taint;
	}
	return cost;
}

#define MOD_IGN (MOD_VOLATILE | MOD_CONST)

static int compare_types(int op, struct symbol *left, struct symbol *right)
{
	struct ctype c1 = {.base_type = left};
	struct ctype c2 = {.base_type = right};
	switch (op) {
	case SPECIAL_EQUAL:
		return !type_difference(&c1, &c2, MOD_IGN, MOD_IGN);
	case SPECIAL_NOTEQUAL:
		return type_difference(&c1, &c2, MOD_IGN, MOD_IGN) != NULL;
	case '<':
		return left->bit_size < right->bit_size;
	case '>':
		return left->bit_size > right->bit_size;
	case SPECIAL_LTE:
		return left->bit_size <= right->bit_size;
	case SPECIAL_GTE:
		return left->bit_size >= right->bit_size;
	}
	return 0;
}

static int expand_compare(struct expression *expr)
{
	struct expression *left = expr->left, *right = expr->right;
	int cost;

	cost = expand_expression(left);
	cost += expand_expression(right);

	if (left && right) {
		/* Type comparison? */
		if (left->type == EXPR_TYPE && right->type == EXPR_TYPE) {
			int op = expr->op;
			expr->type = EXPR_VALUE;
			expr->value = compare_types(op, left->symbol, right->symbol);
			expr->taint = 0;
			return 0;
		}
		if (simplify_cmp_binop(expr, left->ctype))
			return 0;
		if (simplify_float_cmp(expr, left->ctype))
			return 0;
	}
	return cost + 1;
}

static int expand_conditional(struct expression *expr)
{
	struct expression *cond = expr->conditional;
	struct expression *true = expr->cond_true;
	struct expression *false = expr->cond_false;
	int cost, cond_cost;

	cond_cost = expand_expression(cond);
	if (cond->type == EXPR_VALUE) {
		unsigned flags = expr->flags;
		if (!cond->value)
			true = false;
		if (!true)
			true = cond;
		cost = expand_expression(true);
		*expr = *true;
		expr->flags = flags;
		if (expr->type == EXPR_VALUE)
			expr->taint |= cond->taint;
		return cost;
	}

	cost = expand_expression(true);
	cost += expand_expression(false);

	if (cost < SELECT_COST) {
		expr->type = EXPR_SELECT;
		cost -= BRANCH_COST - 1;
	}

	return cost + cond_cost + BRANCH_COST;
}
		
static int expand_assignment(struct expression *expr)
{
	expand_expression(expr->left);
	expand_expression(expr->right);
	return SIDE_EFFECTS;
}

static int expand_addressof(struct expression *expr)
{
	return expand_expression(expr->unop);
}

/*
 * Look up a trustable initializer value at the requested offset.
 *
 * Return NULL if no such value can be found or statically trusted.
 *
 * FIXME!! We should check that the size is right!
 */
static struct expression *constant_symbol_value(struct symbol *sym, int offset)
{
	struct expression *value;

	if (sym->ctype.modifiers & (MOD_ASSIGNED | MOD_ADDRESSABLE))
		return NULL;
	value = sym->initializer;
	if (!value)
		return NULL;
	if (value->type == EXPR_INITIALIZER) {
		struct expression *entry;
		FOR_EACH_PTR(value->expr_list, entry) {
			if (entry->type != EXPR_POS) {
				if (offset)
					continue;
				return entry;
			}
			if (entry->init_offset < offset)
				continue;
			if (entry->init_offset > offset)
				return NULL;
			return entry->init_expr;
		} END_FOR_EACH_PTR(entry);
		return NULL;
	}
	return value;
}

static int expand_dereference(struct expression *expr)
{
	struct expression *unop = expr->unop;
	unsigned int offset;

	expand_expression(unop);

	/*
	 * NOTE! We get a bogus warning right now for some special
	 * cases: apparently I've screwed up the optimization of
	 * a zero-offset dereference, and the ctype is wrong.
	 *
	 * Leave the warning in anyway, since this is also a good
	 * test for me to get the type evaluation right..
	 */
	if (expr->ctype->ctype.modifiers & MOD_NODEREF)
		warning(unop->pos, "dereference of noderef expression");

	/*
	 * Is it "symbol" or "symbol + offset"?
	 */
	offset = 0;
	if (unop->type == EXPR_BINOP && unop->op == '+') {
		struct expression *right = unop->right;
		if (right->type == EXPR_VALUE) {
			offset = right->value;
			unop = unop->left;
		}
	}

	if (unop->type == EXPR_SYMBOL) {
		struct symbol *sym = unop->symbol;
		struct expression *value = constant_symbol_value(sym, offset);

		/* Const symbol with a constant initializer? */
		if (value) {
			/* FIXME! We should check that the size is right! */
			if (value->type == EXPR_VALUE) {
				expr->type = EXPR_VALUE;
				expr->value = value->value;
				expr->taint = 0;
				return 0;
			} else if (value->type == EXPR_FVALUE) {
				expr->type = EXPR_FVALUE;
				expr->fvalue = value->fvalue;
				return 0;
			}
		}

		/* Direct symbol dereference? Cheap and safe */
		return (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN)) ? 2 : 1;
	}

	return UNSAFE;
}

static int simplify_preop(struct expression *expr)
{
	struct expression *op = expr->unop;
	unsigned long long v, mask;

	if (op->type != EXPR_VALUE)
		return 0;

	mask = 1ULL << (expr->ctype->bit_size-1);
	v = op->value;
	switch (expr->op) {
	case '+': break;
	case '-':
		if (v == mask && !(expr->ctype->ctype.modifiers & MOD_UNSIGNED))
			goto Overflow;
		v = -v;
		break;
	case '!': v = !v; break;
	case '~': v = ~v; break;
	default: return 0;
	}
	mask = mask | (mask-1);
	expr->value = v & mask;
	expr->type = EXPR_VALUE;
	expr->taint = op->taint;
	return 1;

Overflow:
	if (!conservative)
		warning(expr->pos, "constant integer operation overflow");
	return 0;
}

static int simplify_float_preop(struct expression *expr)
{
	struct expression *op = expr->unop;
	long double v;

	if (op->type != EXPR_FVALUE)
		return 0;
	v = op->fvalue;
	switch (expr->op) {
	case '+': break;
	case '-': v = -v; break;
	default: return 0;
	}
	expr->fvalue = v;
	expr->type = EXPR_FVALUE;
	return 1;
}

/*
 * Unary post-ops: x++ and x--
 */
static int expand_postop(struct expression *expr)
{
	expand_expression(expr->unop);
	return SIDE_EFFECTS;
}

static int expand_preop(struct expression *expr)
{
	int cost;

	switch (expr->op) {
	case '*':
		return expand_dereference(expr);

	case '&':
		return expand_addressof(expr);

	case SPECIAL_INCREMENT:
	case SPECIAL_DECREMENT:
		/*
		 * From a type evaluation standpoint the preops are
		 * the same as the postops
		 */
		return expand_postop(expr);

	default:
		break;
	}
	cost = expand_expression(expr->unop);

	if (simplify_preop(expr))
		return 0;
	if (simplify_float_preop(expr))
		return 0;
	return cost + 1;
}

static int expand_arguments(struct expression_list *head)
{
	int cost = 0;
	struct expression *expr;

	FOR_EACH_PTR (head, expr) {
		cost += expand_expression(expr);
	} END_FOR_EACH_PTR(expr);
	return cost;
}

static int expand_cast(struct expression *expr)
{
	int cost;
	struct expression *target = expr->cast_expression;

	cost = expand_expression(target);

	/* Simplify normal integer casts.. */
	if (target->type == EXPR_VALUE || target->type == EXPR_FVALUE) {
		cast_value(expr, expr->ctype, target, target->ctype);
		return 0;
	}
	return cost + 1;
}

/* The arguments are constant if the cost of all of them is zero */
int expand_constant_p(struct expression *expr, int cost)
{
	expr->type = EXPR_VALUE;
	expr->value = !cost;
	expr->taint = 0;
	return 0;
}

/* The arguments are safe, if their cost is less than SIDE_EFFECTS */
int expand_safe_p(struct expression *expr, int cost)
{
	expr->type = EXPR_VALUE;
	expr->value = (cost < SIDE_EFFECTS);
	expr->taint = 0;
	return 0;
}

/*
 * expand a call expression with a symbol. This
 * should expand builtins.
 */
static int expand_symbol_call(struct expression *expr, int cost)
{
	struct expression *fn = expr->fn;
	struct symbol *ctype = fn->ctype;

	if (fn->type != EXPR_PREOP)
		return SIDE_EFFECTS;

	if (ctype->op && ctype->op->expand)
		return ctype->op->expand(expr, cost);

	if (ctype->ctype.modifiers & MOD_PURE)
		return 0;

	return SIDE_EFFECTS;
}

static int expand_call(struct expression *expr)
{
	int cost;
	struct symbol *sym;
	struct expression *fn = expr->fn;

	cost = expand_arguments(expr->args);
	sym = fn->ctype;
	if (!sym) {
		expression_error(expr, "function has no type");
		return SIDE_EFFECTS;
	}
	if (sym->type == SYM_NODE)
		return expand_symbol_call(expr, cost);

	return SIDE_EFFECTS;
}

static int expand_expression_list(struct expression_list *list)
{
	int cost = 0;
	struct expression *expr;

	FOR_EACH_PTR(list, expr) {
		cost += expand_expression(expr);
	} END_FOR_EACH_PTR(expr);
	return cost;
}

/* 
 * We can simplify nested position expressions if
 * this is a simple (single) positional expression.
 */
static int expand_pos_expression(struct expression *expr)
{
	struct expression *nested = expr->init_expr;
	unsigned long offset = expr->init_offset;
	int nr = expr->init_nr;

	if (nr == 1) {
		switch (nested->type) {
		case EXPR_POS:
			offset += nested->init_offset;
			*expr = *nested;
			expr->init_offset = offset;
			nested = expr;
			break;

		case EXPR_INITIALIZER: {
			struct expression *reuse = nested, *entry;
			*expr = *nested;
			FOR_EACH_PTR(expr->expr_list, entry) {
				if (entry->type == EXPR_POS) {
					entry->init_offset += offset;
				} else {
					if (!reuse) {
						/*
						 * This happens rarely, but it can happen
						 * with bitfields that are all at offset
						 * zero..
						 */
						reuse = alloc_expression(entry->pos, EXPR_POS);
					}
					reuse->type = EXPR_POS;
					reuse->ctype = entry->ctype;
					reuse->init_offset = offset;
					reuse->init_nr = 1;
					reuse->init_expr = entry;
					REPLACE_CURRENT_PTR(entry, reuse);
					reuse = NULL;
				}
			} END_FOR_EACH_PTR(entry);
			nested = expr;
			break;
		}

		default:
			break;
		}
	}
	return expand_expression(nested);
}

static unsigned long bit_offset(const struct expression *expr)
{
	unsigned long offset = 0;
	while (expr->type == EXPR_POS) {
		offset += bytes_to_bits(expr->init_offset);
		expr = expr->init_expr;
	}
	if (expr && expr->ctype)
		offset += expr->ctype->bit_offset;
	return offset;
}

static int compare_expressions(const void *_a, const void *_b)
{
	const struct expression *a = _a;
	const struct expression *b = _b;
	unsigned long a_pos = bit_offset(a);
	unsigned long b_pos = bit_offset(b);

	return (a_pos < b_pos) ? -1 : (a_pos == b_pos) ? 0 : 1;
}

static void sort_expression_list(struct expression_list **list)
{
	sort_list((struct ptr_list **)list, compare_expressions);
}

static void verify_nonoverlapping(struct expression_list **list)
{
	struct expression *a = NULL;
	struct expression *b;

	FOR_EACH_PTR(*list, b) {
		if (!b->ctype || !b->ctype->bit_size)
			continue;
		if (a && bit_offset(a) == bit_offset(b)) {
			warning(a->pos, "Initializer entry defined twice");
			info(b->pos, "  also defined here");
			return;
		}
		a = b;
	} END_FOR_EACH_PTR(b);
}

static int expand_expression(struct expression *expr)
{
	if (!expr)
		return 0;
	if (!expr->ctype || expr->ctype == &bad_ctype)
		return UNSAFE;

	switch (expr->type) {
	case EXPR_VALUE:
	case EXPR_FVALUE:
	case EXPR_STRING:
		return 0;
	case EXPR_TYPE:
	case EXPR_SYMBOL:
		return expand_symbol_expression(expr);
	case EXPR_BINOP:
		return expand_binop(expr);

	case EXPR_LOGICAL:
		return expand_logical(expr);

	case EXPR_COMMA:
		return expand_comma(expr);

	case EXPR_COMPARE:
		return expand_compare(expr);

	case EXPR_ASSIGNMENT:
		return expand_assignment(expr);

	case EXPR_PREOP:
		return expand_preop(expr);

	case EXPR_POSTOP:
		return expand_postop(expr);

	case EXPR_CAST:
	case EXPR_FORCE_CAST:
	case EXPR_IMPLIED_CAST:
		return expand_cast(expr);

	case EXPR_CALL:
		return expand_call(expr);

	case EXPR_DEREF:
		warning(expr->pos, "we should not have an EXPR_DEREF left at expansion time");
		return UNSAFE;

	case EXPR_SELECT:
	case EXPR_CONDITIONAL:
		return expand_conditional(expr);

	case EXPR_STATEMENT: {
		struct statement *stmt = expr->statement;
		int cost = expand_statement(stmt);

		if (stmt->type == STMT_EXPRESSION && stmt->expression)
			*expr = *stmt->expression;
		return cost;
	}

	case EXPR_LABEL:
		return 0;

	case EXPR_INITIALIZER:
		sort_expression_list(&expr->expr_list);
		verify_nonoverlapping(&expr->expr_list);
		return expand_expression_list(expr->expr_list);

	case EXPR_IDENTIFIER:
		return UNSAFE;

	case EXPR_INDEX:
		return UNSAFE;

	case EXPR_SLICE:
		return expand_expression(expr->base) + 1;

	case EXPR_POS:
		return expand_pos_expression(expr);

	case EXPR_SIZEOF:
	case EXPR_PTRSIZEOF:
	case EXPR_ALIGNOF:
	case EXPR_OFFSETOF:
		expression_error(expr, "internal front-end error: sizeof in expansion?");
		return UNSAFE;
	}
	return SIDE_EFFECTS;
}

static void expand_const_expression(struct expression *expr, const char *where)
{
	if (expr) {
		expand_expression(expr);
		if (expr->type != EXPR_VALUE)
			expression_error(expr, "Expected constant expression in %s", where);
	}
}

int expand_symbol(struct symbol *sym)
{
	int retval;
	struct symbol *base_type;

	if (!sym)
		return 0;
	base_type = sym->ctype.base_type;
	if (!base_type)
		return 0;

	retval = expand_expression(sym->initializer);
	/* expand the body of the symbol */
	if (base_type->type == SYM_FN) {
		if (base_type->stmt)
			expand_statement(base_type->stmt);
	}
	return retval;
}

static void expand_return_expression(struct statement *stmt)
{
	expand_expression(stmt->expression);
}

static int expand_if_statement(struct statement *stmt)
{
	struct expression *expr = stmt->if_conditional;

	if (!expr || !expr->ctype || expr->ctype == &bad_ctype)
		return UNSAFE;

	expand_expression(expr);

/* This is only valid if nobody jumps into the "dead" side */
#if 0
	/* Simplify constant conditionals without even evaluating the false side */
	if (expr->type == EXPR_VALUE) {
		struct statement *simple;
		simple = expr->value ? stmt->if_true : stmt->if_false;

		/* Nothing? */
		if (!simple) {
			stmt->type = STMT_NONE;
			return 0;
		}
		expand_statement(simple);
		*stmt = *simple;
		return SIDE_EFFECTS;
	}
#endif
	expand_statement(stmt->if_true);
	expand_statement(stmt->if_false);
	return SIDE_EFFECTS;
}

/*
 * Expanding a compound statement is really just
 * about adding up the costs of each individual
 * statement.
 *
 * We also collapse a simple compound statement:
 * this would trigger for simple inline functions,
 * except we would have to check the "return"
 * symbol usage. Next time.
 */
static int expand_compound(struct statement *stmt)
{
	struct statement *s, *last;
	int cost, statements;

	if (stmt->ret)
		expand_symbol(stmt->ret);

	last = stmt->args;
	cost = expand_statement(last);
	statements = last != NULL;
	FOR_EACH_PTR(stmt->stmts, s) {
		statements++;
		last = s;
		cost += expand_statement(s);
	} END_FOR_EACH_PTR(s);

	if (statements == 1 && !stmt->ret)
		*stmt = *last;

	return cost;
}

static int expand_statement(struct statement *stmt)
{
	if (!stmt)
		return 0;

	switch (stmt->type) {
	case STMT_DECLARATION: {
		struct symbol *sym;
		FOR_EACH_PTR(stmt->declaration, sym) {
			expand_symbol(sym);
		} END_FOR_EACH_PTR(sym);
		return SIDE_EFFECTS;
	}

	case STMT_RETURN:
		expand_return_expression(stmt);
		return SIDE_EFFECTS;

	case STMT_EXPRESSION:
		return expand_expression(stmt->expression);

	case STMT_COMPOUND:
		return expand_compound(stmt);

	case STMT_IF:
		return expand_if_statement(stmt);

	case STMT_ITERATOR:
		expand_expression(stmt->iterator_pre_condition);
		expand_expression(stmt->iterator_post_condition);
		expand_statement(stmt->iterator_pre_statement);
		expand_statement(stmt->iterator_statement);
		expand_statement(stmt->iterator_post_statement);
		return SIDE_EFFECTS;

	case STMT_SWITCH:
		expand_expression(stmt->switch_expression);
		expand_statement(stmt->switch_statement);
		return SIDE_EFFECTS;

	case STMT_CASE:
		expand_const_expression(stmt->case_expression, "case statement");
		expand_const_expression(stmt->case_to, "case statement");
		expand_statement(stmt->case_statement);
		return SIDE_EFFECTS;

	case STMT_LABEL:
		expand_statement(stmt->label_statement);
		return SIDE_EFFECTS;

	case STMT_GOTO:
		expand_expression(stmt->goto_expression);
		return SIDE_EFFECTS;

	case STMT_NONE:
		break;
	case STMT_ASM:
		/* FIXME! Do the asm parameter evaluation! */
		break;
	case STMT_CONTEXT:
		expand_expression(stmt->expression);
		break;
	case STMT_RANGE:
		expand_expression(stmt->range_expression);
		expand_expression(stmt->range_low);
		expand_expression(stmt->range_high);
		break;
	}
	return SIDE_EFFECTS;
}

static inline int bad_integer_constant_expression(struct expression *expr)
{
	if (!(expr->flags & Int_const_expr))
		return 1;
	if (expr->taint & Taint_comma)
		return 1;
	return 0;
}

static long long __get_expression_value(struct expression *expr, int strict)
{
	long long value, mask;
	struct symbol *ctype;

	if (!expr)
		return 0;
	ctype = evaluate_expression(expr);
	if (!ctype) {
		expression_error(expr, "bad constant expression type");
		return 0;
	}
	expand_expression(expr);
	if (expr->type != EXPR_VALUE) {
		if (strict != 2)
			expression_error(expr, "bad constant expression");
		return 0;
	}
	if ((strict == 1) && bad_integer_constant_expression(expr)) {
		expression_error(expr, "bad integer constant expression");
		return 0;
	}

	value = expr->value;
	mask = 1ULL << (ctype->bit_size-1);

	if (value & mask) {
		while (ctype->type != SYM_BASETYPE)
			ctype = ctype->ctype.base_type;
		if (!(ctype->ctype.modifiers & MOD_UNSIGNED))
			value = value | mask | ~(mask-1);
	}
	return value;
}

long long get_expression_value(struct expression *expr)
{
	return __get_expression_value(expr, 0);
}

long long const_expression_value(struct expression *expr)
{
	return __get_expression_value(expr, 1);
}

long long get_expression_value_silent(struct expression *expr)
{

	return __get_expression_value(expr, 2);
}

int is_zero_constant(struct expression *expr)
{
	const int saved = conservative;
	conservative = 1;
	expand_expression(expr);
	conservative = saved;
	return expr->type == EXPR_VALUE && !expr->value;
}
