~mcf/cproc

16c718729adfaf40cf22aa4efeafb0d92ef5ee3c — Michael Forney 1 year, 9 months ago a1b0a66
Prepare for supporting architecture-specific va_list type
3 files changed, 28 insertions(+), 17 deletions(-)

M cc.h
M expr.c
M type.c
M cc.h => cc.h +1 -1
@@ 428,7 428,7 @@ extern struct type typeint, typeuint;
extern struct type typelong, typeulong;
extern struct type typellong, typeullong;
extern struct type typefloat, typedouble, typeldouble;
extern struct type typevalist, typevalistptr;
extern struct type typevalist;

/* targ */


M expr.c => expr.c +22 -7
@@ 642,26 642,41 @@ builtinfunc(struct scope *s, enum builtinkind kind)
	case BUILTINVAARG:
		e = mkexpr(EXPRBUILTIN, NULL);
		e->builtin.kind = BUILTINVAARG;
		e->base = exprconvert(assignexpr(s), &typevalistptr);
		e->base = mkunaryexpr(TBAND, assignexpr(s));
		if (e->base->base->type != &typevalist)
			error(&tok.loc, "va_arg argument must have type va_list");
		expect(TCOMMA, "after va_list");
		e->type = typename(s, &e->qual);
		break;
	case BUILTINVACOPY:
		e = mkexpr(EXPRASSIGN, typevalist.base);
		e->assign.l = mkunaryexpr(TMUL, exprconvert(assignexpr(s), &typevalistptr));
		e = mkexpr(EXPRASSIGN, &typevoid);
		e->assign.l = assignexpr(s);
		if (e->assign.l->decayed)
			e->assign.l = e->assign.l->base;
		if (e->assign.l->type != &typevalist)
			error(&tok.loc, "va_copy destination must have type va_list");
		expect(TCOMMA, "after target va_list");
		e->assign.r = mkunaryexpr(TMUL, exprconvert(assignexpr(s), &typevalistptr));
		e = exprconvert(e, &typevoid);
		e->assign.r = assignexpr(s);
		if (e->assign.r->decayed)
			e->assign.r = e->assign.r->base;
		if (e->assign.r->type != &typevalist)
			error(&tok.loc, "va_copy source must have type va_list");
		break;
	case BUILTINVAEND:
		e = assignexpr(s);
		if (e->decayed)
			e = e->base;
		if (e->type != &typevalist)
			error(&tok.loc, "va_end argument must have type va_list");
		e = mkexpr(EXPRBUILTIN, &typevoid);
		e->builtin.kind = BUILTINVAEND;
		exprconvert(assignexpr(s), &typevalistptr);
		break;
	case BUILTINVASTART:
		e = mkexpr(EXPRBUILTIN, &typevoid);
		e->builtin.kind = BUILTINVASTART;
		e->base = exprconvert(assignexpr(s), &typevalistptr);
		e->base = mkunaryexpr(TBAND, assignexpr(s));
		if (e->base->base->type != &typevalist)
			error(&tok.loc, "va_start argument must have type va_list");
		expect(TCOMMA, "after va_list");
		param = assignexpr(s);
		if (param->kind != EXPRIDENT)

M type.c => type.c +5 -9
@@ 39,17 39,13 @@ struct type typefloat   = FLTTYPE(TYPEFLOAT, 4);
struct type typedouble  = FLTTYPE(TYPEDOUBLE, 8);
struct type typeldouble = FLTTYPE(TYPELDOUBLE, 16);

static struct type typevaliststruct = {
	.kind = TYPESTRUCT, .size = 32, .align = 8,
	.prop = PROPOBJECT|PROPAGGR,
};
struct type typevalist = {
	.kind = TYPEARRAY, .size = 32, .align = 8, .array = {1}, .base = &typevaliststruct,
	.kind = TYPEARRAY, .size = 32, .align = 8, .array = {1},
	.prop = PROPOBJECT|PROPDERIVED|PROPAGGR,
};
struct type typevalistptr = {
	.kind = TYPEPOINTER, .size = 8, .align = 8, .base = &typevaliststruct,
	.prop = PROPOBJECT|PROPDERIVED|PROPSCALAR,
	.base = &(struct type){
		.kind = TYPESTRUCT, .size = 32, .align = 8,
		.prop = PROPOBJECT|PROPAGGR,
	},
};

struct type *