Exemple #1
0
void fold_expr_if(expr *e, symtable *stab)
{
	enum constyness is_const;
	intval dummy;

	fold_expr(e->expr, stab);
	const_fold(e->expr, &dummy, &is_const);

	if(is_const != CONST_NO)
		POSSIBLE_OPT(e->expr, "constant ?: expression");

	fold_need_expr(e->expr, "?: expr", 1);
	fold_disallow_st_un(e->expr, "?: expr");

	if(e->lhs){
		fold_expr(e->lhs, stab);
		fold_disallow_st_un(e->lhs, "?: lhs");
	}

	fold_expr(e->rhs, stab);
	fold_disallow_st_un(e->rhs, "?: rhs");

	e->tree_type = decl_copy(e->rhs->tree_type); /* TODO: check they're the same */

	e->freestanding = (e->lhs ? e->lhs : e->expr)->freestanding || e->rhs->freestanding;
}
void fold_expr_cast(expr *e, symtable *stab)
{
    fold_expr(e->expr, stab);

    fold_disallow_st_un(e->expr, "cast-expr");

    /*
     * if we don't have a valid tree_type, get one
     * this is only the case where we're involving a tdef or typeof
     */

    if(e->tree_type->type->primitive == type_unknown) {
        decl_free(e->tree_type);
        e->tree_type = decl_copy(e->expr->tree_type);
    }

    fold_decl(e->tree_type, stab); /* struct lookup, etc */

    fold_disallow_st_un(e, "cast-target");

#ifdef CAST_COLLAPSE
    if(expr_kind(e->expr, cast)) {
        /* get rid of e->expr, replace with e->expr->rhs */
        expr *del = e->expr;

        e->expr = e->expr->expr;

        /*decl_free(del->tree_type); XXX: memleak */
        expr_free(del);

        fold_expr_cast(e, stab);
    }
#endif
}
Exemple #3
0
void fold_expr_sizeof(expr *e, symtable *stab)
{
	if(!e->expr->expr_is_sizeof)
		fold_expr(e->expr, stab);

	e->tree_type = decl_new();
	e->tree_type->type->primitive = type_int;
}
void fold_stmt_case_range(stmt *s)
{
	intval lval, rval;

	fold_expr(s->expr,  s->symtab);
	fold_expr(s->expr2, s->symtab);

	const_fold_need_val(s->expr,  &lval);
	const_fold_need_val(s->expr2, &rval);

	fold_need_expr(s->expr,  "case", 0);
	fold_need_expr(s->expr2, "case", 0);

	if(lval.val >= rval.val)
		DIE_AT(&s->where, "case range equal or inverse");

	s->expr->spel = asm_label_case(CASE_RANGE, lval.val);

	fold_stmt_and_add_to_curswitch(s);
}
void fold_stmt_case(stmt *t)
{
	intval val;

	fold_expr(t->expr, t->symtab);
	fold_need_expr(t->expr, "case", 0);
	const_fold_need_val(t->expr, &val);

	t->expr->spel = asm_label_case(CASE_CASE, val.val);

	fold_stmt_and_add_to_curswitch(t);
}
Exemple #6
0
void fold_stmt_if(stmt *s)
{
	symtable *test_symtab = fold_stmt_test_init_expr(s, "if");

	fold_expr(s->expr, test_symtab);

	fold_need_expr(s->expr, s->f_str(), 1);
	OPT_CHECK(s->expr, "constant expression in if");

	fold_stmt(s->lhs);
	if(s->rhs)
		fold_stmt(s->rhs);
}
Exemple #7
0
void fold_expr_funcall(expr *e, symtable *stab)
{
	decl *df;
	funcargs *args_exp;

	if(expr_kind(e->expr, identifier) && e->expr->spel){
		char *const sp = e->expr->spel;

		e->sym = symtab_search(stab, sp);
		if(!e->sym){
			df = decl_new_where(&e->where);

			df->type->primitive = type_int;
			df->type->spec     |= spec_extern;

			cc1_warn_at(&e->where, 0, WARN_IMPLICIT_FUNC, "implicit declaration of function \"%s\"", sp);

			df->spel = sp;

			df->funcargs = funcargs_new();

			if(e->funcargs)
				/* set up the funcargs as if it's "x()" - i.e. any args */
				function_empty_args(df->funcargs);

			e->sym = symtab_add(symtab_root(stab), df, sym_global, SYMTAB_WITH_SYM, SYMTAB_PREPEND);
		}else{
			df = e->sym->decl;
		}

		fold_expr(e->expr, stab);
	}else{
		fold_expr(e->expr, stab);

		/*
		 * convert int (*)() to remove the deref
		 */
		if(decl_is_func_ptr(e->expr->tree_type)){
			/* XXX: memleak */
			e->expr = e->expr->lhs;
			fprintf(stderr, "FUNCPTR\n");
		}else{
			fprintf(stderr, "decl %s\n", decl_to_str(e->expr->tree_type));
		}

		df = e->expr->tree_type;

		if(!decl_is_callable(df)){
			die_at(&e->expr->where, "expression %s (%s) not callable",
					e->expr->f_str(),
					decl_to_str(df));
		}
	}

	e->tree_type = decl_copy(df);
	/*
	 * int (*x)();
	 * (*x)();
	 * evaluates to tree_type = int;
	 */
	decl_func_deref(e->tree_type);


	if(e->funcargs){
		expr **iter;
		for(iter = e->funcargs; *iter; iter++)
			fold_expr(*iter, stab);
	}

	/* func count comparison, only if the func has arg-decls, or the func is f(void) */
	args_exp = decl_funcargs(e->tree_type);

	UCC_ASSERT(args_exp, "no funcargs for decl %s", df->spel);

	if(args_exp->arglist || args_exp->args_void){
		expr **iter_arg;
		decl **iter_decl;
		int count_decl, count_arg;

		count_decl = count_arg = 0;

		for(iter_arg  = e->funcargs;       iter_arg  && *iter_arg;  iter_arg++,  count_arg++);
		for(iter_decl = args_exp->arglist; iter_decl && *iter_decl; iter_decl++, count_decl++);

		if(count_decl != count_arg && (args_exp->variadic ? count_arg < count_decl : 1)){
			die_at(&e->where, "too %s arguments to function %s (got %d, need %d)",
					count_arg > count_decl ? "many" : "few",
					df->spel, count_arg, count_decl);
		}

		if(e->funcargs){
			funcargs *argument_decls = funcargs_new();

			for(iter_arg = e->funcargs; *iter_arg; iter_arg++)
				dynarray_add((void ***)&argument_decls->arglist, (*iter_arg)->tree_type);

			fold_funcargs_equal(args_exp, argument_decls, 1, &e->where, "argument", df->spel);
			funcargs_free(argument_decls, 0);
		}
	}
}