Ejemplo n.º 1
0
static void stmt_walk2(stmt *base, stmt_walk_enter enter, stmt_walk_leave leave, void *data, int *stop)
{
	int descend = 1;

	enter(base, stop, &descend, data);

	if(*stop)
		return;

#define WALK_IF(sub) if(sub){ stmt_walk2(sub, enter, leave, data, stop); if(*stop) return; }

	if(!descend)
		goto fin;

	WALK_IF(base->lhs);
	WALK_IF(base->rhs);

	if(stmt_kind(base, code) && base->bits.code.stmts){
		int i;
		for(i = 0; base->bits.code.stmts[i]; i++){
			stmt_walk2(base->bits.code.stmts[i], enter, leave, data, stop);
			if(*stop)
				break;
		}
	}

fin:
	if(leave)
		leave(base, data);
}
Ejemplo n.º 2
0
/* checks case duplicates, not default */
static void fold_switch_dups(stmt *sw)
{
	typedef int (*qsort_f)(const void *, const void *);

	struct
	{
		numeric start, end;
		stmt *cse;
	} *vals;
	size_t n = dynarray_count(sw->bits.switch_.cases);
	size_t i = 0;
	stmt **titer;

	if(n == 0)
		return;

	vals = malloc(n * sizeof *vals);

	/* gather all switch values */
	ITER_SWITCH(sw, titer){
		stmt *cse = *titer;

		vals[i].cse = cse;

		const_fold_integral(cse->expr, &vals[i].start);

		if(stmt_kind(cse, case_range))
			const_fold_integral(cse->expr2, &vals[i].end);
		else
			memcpy(&vals[i].end, &vals[i].start, sizeof vals[i].end);

		i++;
	}
Ejemplo n.º 3
0
void print_stmt(stmt *t)
{
	idt_printf("statement: %s\n", t->f_str());

	if(t->flow){
		gen_str_indent++;
		print_stmt_flow(t->flow);
		gen_str_indent--;
	}

	PRINT_IF(t, expr, print_expr);
	PRINT_IF(t, lhs,  print_stmt);
	PRINT_IF(t, rhs,  print_stmt);
	PRINT_IF(t, rhs,  print_stmt);

	if(stmt_kind(t, code)){
		idt_printf("structs/unions/enums:\n");
		gen_str_indent++;
		print_sues_static_asserts(t->symtab);
		gen_str_indent--;

		if(t->symtab){
			decl **iter;

			idt_printf("stack space %d\n", t->symtab->auto_total_size);
			idt_printf("decls:\n");

			for(iter = t->symtab->decls; iter && *iter; iter++){
				decl *d = *iter;

				gen_str_indent++;
				print_decl(d, PDECL_INDENT
						| PDECL_NEWLINE
						| PDECL_SYM_OFFSET
						| PDECL_ATTR
						| PDECL_PINIT);
				gen_str_indent--;
			}
		}

		if(t->bits.code.stmts){
			stmt **iter;

			idt_printf("code:\n");

			for(iter = t->bits.code.stmts; *iter; iter++){
				gen_str_indent++;
				print_stmt(*iter);
				gen_str_indent--;
			}
		}
	}
}
Ejemplo n.º 4
0
const out_val *gen_expr_stmt(const expr *e, out_ctx *octx)
{
	size_t n;
	const out_val *ret;
	struct out_dbg_lbl *pushed_lbls[2];

	gen_stmt_code_m1(e->code, 1, pushed_lbls, octx);

	n = dynarray_count(e->code->bits.code.stmts);

	if(n > 0 && stmt_kind(e->code->bits.code.stmts[n-1], expr))
		ret = gen_expr(e->code->bits.code.stmts[n - 1]->expr, octx);
	else
		ret = out_new_noop(octx);

	/* this is skipped by gen_stmt_code_m1( ... 1, ... ) */
	gen_stmt_code_m1_finish(e->code, pushed_lbls, octx);

	return ret;
}
Ejemplo n.º 5
0
void fold_expr_stmt(expr *e, symtable *stab)
{
	stmt *last_stmt;
	int last;

	(void)stab;

	last = dynarray_count(e->code->bits.code.stmts);
	if(last){
		last_stmt = e->code->bits.code.stmts[last - 1];
		last_stmt->freestanding = 1; /* allow the final to be freestanding */
		last_stmt->expr_no_pop = 1;
	}

	fold_stmt(e->code); /* symtab should've been set by parse */

	if(last && stmt_kind(last_stmt, expr)){
		expr *last_expr = last_stmt->expr;

		e->tree_type = last_expr->tree_type;
		if(fold_check_expr(e,
				FOLD_CHK_ALLOW_VOID,
				"({ ... }) statement"))
		{
			return;
		}

		switch(expr_is_lval(last_expr)){
			case LVALUE_NO:
				break;
			case LVALUE_STRUCT:
			case LVALUE_USER_ASSIGNABLE:
				e->f_islval = expr_is_lval_struct;
		}
	}else{
		e->tree_type = type_nav_btype(cc1_type_nav, type_void);
	}

	e->freestanding = 1; /* ({ ... }) on its own is freestanding */
}