Exemple #1
0
static void bitfield_val_set(
		struct bitfield_val *bfv, expr *kval, expr *field_w)
{
	bfv->val = kval ? const_fold_val_i(kval) : 0;
	bfv->offset = 0;
	bfv->width = const_fold_val_i(field_w);
}
static int decl_cmp_ctor_dtor_pri(
		const void *a, const void *b, enum attribute_type attr_ty)
{
	decl *da = *(decl **)a, *db = *(decl **)b;
	attribute *attr_a = attribute_present(da, attr_ty);
	attribute *attr_b = attribute_present(db, attr_ty);

	assert(attr_a && attr_b);

	{
		struct expr *exp_a = attr_a->bits.priority;
		struct expr *exp_b = attr_b->bits.priority;
		integral_t ia, ib;

		switch(!!exp_a + !!exp_b){
			case 0:
				return 0;

			case 1:
				return exp_a ? -1 : 1;

			case 2:
				break;

			default:
				assert(0);
		}

		ia = const_fold_val_i(exp_a);
		ib = const_fold_val_i(exp_b);

		return ia - ib;
	}
}
void style_stmt_case_range(stmt *s)
{
	stylef("\ncase %ld ... %ld: ",
			(long)const_fold_val_i(s->expr),
			(long)const_fold_val_i(s->expr2));

	gen_stmt(s->lhs);
}
static void gen_expr_struct_lea(expr *e)
{
	ASSERT_NOT_DOT();

	gen_expr(e->lhs);

	/* cast for void* arithmetic */
	out_change_type(type_ptr_to(type_nav_btype(cc1_type_nav, type_void)));
	out_push_l(type_nav_btype(cc1_type_nav, type_intptr_t), struct_offset(e)); /* integral offset */
	out_op(op_plus);

	if(fopt_mode & FOPT_VERBOSE_ASM)
		out_comment("struct member %s", e->bits.struct_mem.d->spel);


	{
		decl *d = e->bits.struct_mem.d;

		out_change_type(type_ptr_to(d->ref));

		/* set if we're a bitfield - out_deref() and out_store()
		 * i.e. read + write then handle this
		 */
		if(d->bits.var.field_width){
			unsigned w = const_fold_val_i(d->bits.var.field_width);
			out_set_bitfield(d->bits.var.struct_offset_bitfield, w);
			out_comment("struct bitfield lea");
		}
	}
}
Exemple #5
0
unsigned type_size(type *r, const where *from)
{
	switch(r->type){
		case type_auto:
			ICE("__auto_type");

		case type_btype:
			return btype_size(r->bits.type, from);

		case type_tdef:
		{
			decl *d = r->bits.tdef.decl;
			type *sub;

			if(d)
				return type_size(d->ref, from);

			sub = r->bits.tdef.type_of->tree_type;
			UCC_ASSERT(sub, "type_size for unfolded typedef");
			return type_size(sub, from);
		}

		case type_attr:
		case type_cast:
		case type_where:
			return type_size(r->ref, from);

		case type_ptr:
		case type_block:
			return platform_word_size();

		case type_func:
			/* function size is one, sizeof(main) is valid */
			return 1;

		case type_array:
		{
			integral_t sz;

			if(type_is_void(r->ref))
				die_at(from, "array of void");

			if(!r->bits.array.size)
				die_at(from, "array has an incomplete size");

			sz = const_fold_val_i(r->bits.array.size);

			return sz * type_size(r->ref, from);
		}
	}

	ucc_unreach(0);
}
void fold_stmt_case_range(stmt *s)
{
	integral_t lv, rv;

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

	fold_check_expr(s->expr,
			FOLD_CHK_INTEGRAL | FOLD_CHK_CONST_I,
			"case-range");
	lv = const_fold_val_i(s->expr);

	fold_check_expr(s->expr2,
			FOLD_CHK_INTEGRAL | FOLD_CHK_CONST_I,
			"case-range");
	rv = const_fold_val_i(s->expr2);

	if(lv >= rv)
		die_at(&s->where, "case range equal or inverse");

	s->bits.case_lbl = out_label_case(CASE_RANGE, lv);
	fold_stmt_and_add_to_curswitch(s, &s->bits.case_lbl);
}
Exemple #7
0
static void print_enum(struct_union_enum_st *et)
{
	sue_member **mi;

	idt_printf("enum %s:\n", et->spel);

	gen_str_indent++;
	for(mi = et->members; *mi; mi++){
		enum_member *m = (*mi)->enum_member;

		idt_printf("member %s = %" NUMERIC_FMT_D "\n",
				m->spel, const_fold_val_i(m->val));
	}
	gen_str_indent--;
}
void gen_expr_str_struct(expr *e)
{
	decl *mem = e->bits.struct_mem.d;

	idt_printf("struct/union member %s offset %d\n",
			mem->spel, struct_offset(e));

	if(mem->bits.var.field_width)
		idt_printf("bitfield offset %u, width %u\n",
				mem->bits.var.struct_offset_bitfield,
				(unsigned)const_fold_val_i(mem->bits.var.field_width));

	gen_str_indent++;
	print_expr(e->lhs);
	gen_str_indent--;
}
Exemple #9
0
type *decl_type_for_bitfield(decl *d)
{
	assert(!type_is(d->ref, type_func));

	if(d->bits.var.field_width){
		const unsigned bits = const_fold_val_i(d->bits.var.field_width);
		const int is_signed = type_is_signed(d->ref);
		unsigned bytes = bits / CHAR_BIT;

		/* need to add on a byte for any leftovers */
		if(bits % CHAR_BIT)
			bytes++;

		return type_nav_MAX_FOR(cc1_type_nav, bytes, is_signed);
	}else{
		return d->ref;
	}
}
Exemple #10
0
static void print_struct(struct_union_enum_st *sue)
{
	sue_member **iter;

	if(!sue_complete(sue)){
		idt_printf("incomplete %s %s\n", sue_str(sue), sue->spel);
		return;
	}

	idt_printf("%s %s (size %d):\n", sue_str(sue), sue->spel, sue_size(sue, &sue->where));

	gen_str_indent++;
	for(iter = sue->members; iter && *iter; iter++){
		decl *d = (*iter)->struct_member;

		idt_printf("decl %s:\n", d->spel ? d->spel : "<anon>");
		gen_str_indent++;
		print_decl(d, PDECL_INDENT | PDECL_NEWLINE | PDECL_ATTR);

		if(!type_is(d->ref, type_func)){
#define SHOW_FIELD(nam) idt_printf("." #nam " = %u\n", d->bits.var.nam)
			SHOW_FIELD(struct_offset);

			if(d->bits.var.field_width){
				integral_t v = const_fold_val_i(d->bits.var.field_width);

				gen_str_indent++;

				idt_printf(".field_width = %" NUMERIC_FMT_D "\n", v);

				SHOW_FIELD(struct_offset_bitfield);

				gen_str_indent--;
			}
		}

		gen_str_indent--;
	}
	gen_str_indent--;
}
Exemple #11
0
static enum type_cmp type_cmp_r(
		type *const orig_a,
		type *const orig_b,
		enum type_cmp_opts opts)
{
	enum type_cmp ret;
	type *a, *b;
	int subchk = 1;

	if(!orig_a || !orig_b)
		return orig_a == orig_b ? TYPE_EQUAL : TYPE_NOT_EQUAL;

	a = type_skip_all(orig_a);
	b = type_skip_all(orig_b);

	/* array/func decay takes care of any array->ptr checks */
	if(a->type != b->type){
		/* allow _Bool <- pointer */
		if(type_is_primitive(a, type__Bool) && type_is_ptr(b))
			return TYPE_CONVERTIBLE_IMPLICIT;

		/* allow int <-> ptr (or block) */
		if((type_is_ptr_or_block(a) && type_is_integral(b))
		|| (type_is_ptr_or_block(b) && type_is_integral(a)))
		{
			return TYPE_CONVERTIBLE_EXPLICIT;
		}

		/* allow void <- anything */
		if(type_is_void(a))
			return TYPE_CONVERTIBLE_IMPLICIT;

		/* allow block <-> fnptr */
		if((type_is_fptr(a) && type_is(b, type_block))
		|| (type_is_fptr(b) && type_is(a, type_block)))
		{
			return TYPE_CONVERTIBLE_EXPLICIT;
		}

		return TYPE_NOT_EQUAL;
	}

	switch(a->type){
		case type_auto:
			ICE("__auto_type");

		case type_btype:
			subchk = 0;
			ret = btype_cmp(a->bits.type, b->bits.type);
			break;

		case type_array:
			if(a->bits.array.is_vla || b->bits.array.is_vla){
				/* fine, pretend they're equal even if different expressions */
				ret = TYPE_EQUAL_TYPEDEF;

			}else{
				const int a_has_sz = !!a->bits.array.size;
				const int b_has_sz = !!b->bits.array.size;

				if(a_has_sz && b_has_sz){
					integral_t av = const_fold_val_i(a->bits.array.size);
					integral_t bv = const_fold_val_i(b->bits.array.size);

					if(av != bv)
						return TYPE_NOT_EQUAL;
				}else if(a_has_sz != b_has_sz){
					if((opts & TYPE_CMP_ALLOW_TENATIVE_ARRAY) == 0)
						return TYPE_NOT_EQUAL;
				}
			}

			/* next */
			break;

		case type_block:
		case type_ptr:
			break;

		case type_cast:
		case type_tdef:
		case type_attr:
		case type_where:
			ICE("should've been skipped");

		case type_func:
			switch(funcargs_cmp(a->bits.func.args, b->bits.func.args)){
				case FUNCARGS_EXACT_EQUAL:
				case FUNCARGS_IMPLICIT_CONV:
					break;
				default:
					/* "void (int)" and "void (int, int)" aren't equal,
					 * but a cast can soon fix it */
					return TYPE_CONVERTIBLE_EXPLICIT;
			}
			break;
	}

	if(subchk)
		ret = type_cmp_r(a->ref, b->ref, opts);

	if(ret == TYPE_NOT_EQUAL
	&& a->type == type_func)
	{
		/* "int (int)" and "void (int)" aren't equal - but castable */
		ret = TYPE_CONVERTIBLE_EXPLICIT;
	}

	if(ret == TYPE_NOT_EQUAL
	&& a->type == type_ptr
	&& fopt_mode & FOPT_PLAN9_EXTENSIONS)
	{
		/* allow b to be an anonymous member of a, if pointers */
		struct_union_enum_st *a_sue = type_is_s_or_u(a),
		                     *b_sue = type_is_s_or_u(b);

		if(a_sue && b_sue /* already know they aren't equal */){
			/* b_sue has an a_sue,
			 * the implicit cast adjusts to return said a_sue */
			if(struct_union_member_find_sue(b_sue, a_sue))
				return TYPE_CONVERTIBLE_IMPLICIT;
		}
	}

	/* allow ptr <-> ptr */
	if(ret == TYPE_NOT_EQUAL && type_is_ptr(a) && type_is_ptr(b))
		ret = TYPE_CONVERTIBLE_EXPLICIT;

	/* char * and int * are explicitly conv.,
	 * even though char and int are implicit */
	if(ret == TYPE_CONVERTIBLE_IMPLICIT && a->type == type_ptr)
		ret = TYPE_CONVERTIBLE_EXPLICIT;

	if(a->type == type_ptr || a->type == type_block){
		switch(ret){
#define MAP(a, b) case a: ret = b; break
			MAP(TYPE_QUAL_ADD, TYPE_QUAL_POINTED_ADD);
			MAP(TYPE_QUAL_SUB, TYPE_QUAL_POINTED_SUB);
			MAP(TYPE_QUAL_POINTED_ADD, TYPE_QUAL_NESTED_CHANGE);
			MAP(TYPE_QUAL_POINTED_SUB, TYPE_QUAL_NESTED_CHANGE);
#undef MAP
			default:
				break;
		}
	}

	if(ret & TYPE_EQUAL_ANY){
		enum type_qualifier a_qual = type_qual(orig_a);
		enum type_qualifier b_qual = type_qual(orig_b);

		if(a_qual && b_qual){
			switch(type_qual_cmp(a_qual, b_qual)){
				case -1:
					/* a has more */
					ret = TYPE_QUAL_ADD;
					break;
				case 1:
					/* b has more */
					ret = TYPE_QUAL_SUB;
					break;
			}
		}else if(a_qual){
			ret = TYPE_QUAL_ADD;
		}else if(b_qual){
			ret = TYPE_QUAL_SUB;
		} /* else neither are casts */
	}

	if(ret == TYPE_EQUAL){
		int at = orig_a->type == type_tdef;
		int bt = orig_b->type == type_tdef;

		if(at != bt){
			/* one is a typedef */
			ret = TYPE_EQUAL_TYPEDEF;
		}else if(at){
			/* both typedefs */
			if(orig_a->bits.tdef.decl != orig_b->bits.tdef.decl){
				ret = TYPE_EQUAL_TYPEDEF;
			}
		}
		/* else no typedefs */
	}

	return ret;
}
Exemple #12
0
static void type_add_str(
		type *r, const char *spel,
		int *need_spc,
		char **bufp, int *sz,
		type *stop_at)
{
	int need_paren;
	type *array_qual = NULL, *next_ty;

	if(!r){
		/* reached the bottom/end - spel */
		if(spel){
			ADD_SPC();
			BUF_ADD("%s", spel);
			*need_spc = 0;
		}
		return;
	}

	if(stop_at && r->tmp == stop_at){
		type_add_str(r->tmp, spel, need_spc, bufp, sz, stop_at);
		return;
	}

	type_add_str_pre(r, &need_paren, need_spc, bufp, sz);

	next_ty = r->tmp;
	if(r->type == type_array && r->tmp && r->tmp->type == type_cast){
		array_qual = r->tmp;
		next_ty = array_qual->tmp;
	}

	type_add_str(next_ty, spel, need_spc, bufp, sz, stop_at);

	switch(r->type){
		case type_auto:
			ICE("__auto_type");

		case type_tdef:
			/* tdef "aka: %s" handled elsewhere */
		case type_attr:
			/* attribute not handled here */
		case type_btype:
		case type_cast:
		case type_where:
			/**/
		case type_block:
			break;

		case type_func:
			type_add_funcargs(r->bits.func.args, need_spc, bufp, sz);
			break;

		case type_ptr:
#ifdef SHOW_DECAYED_ARRAYS
			if(!r->bits.ptr.size)
#endif
				break;
			/* fall */
		case type_array:
		{
			const char *sz_space = "";

			BUF_ADD("[");
			if(r->bits.array.is_vla == 0 && r->bits.array.is_static){
				BUF_ADD("static");
				sz_space = " ";
			}

			if(array_qual){
				BUF_ADD("%s%s", sz_space,
						type_qual_to_str(array_qual->bits.cast.qual, 0));
				sz_space = " ";
			}

			switch(r->bits.array.is_vla){
				case 0:
					if(r->bits.array.size){
						BUF_ADD(
								"%s%" NUMERIC_FMT_D,
								sz_space,
								const_fold_val_i(r->bits.array.size));
					}
					break;
				case VLA:
					BUF_ADD("vla");
					break;
				case VLA_STAR:
					BUF_ADD("*");
					break;
			}
			BUF_ADD("]");
			break;
		}
	}

	if(need_paren)
		BUF_ADD(")");
#undef IS_PTR
}