~mcf/cproc

6a00f53cd34e33c12a91942015a3dc5dbcb44bf2 — Michael Forney 2 years ago 1bc3f5f
Abbreviate tag names
16 files changed, 244 insertions(+), 246 deletions(-)

M backend.h
M decl.c
M decl.h
M eval.c
M eval.h
M expr.c
M expr.h
M init.c
M init.h
M qbe.c
M scope.c
M scope.h
M stmt.c
M stmt.h
M type.c
M type.h
M backend.h => backend.h +20 -20
@@ 8,10 8,10 @@ struct switchcases {
	struct value *defaultlabel;
};

struct representation;
struct declaration;
struct expression;
struct initializer;
struct repr;
struct decl;
struct expr;
struct init;
struct scope;
struct type;



@@ 20,22 20,22 @@ void switchcase(struct switchcases *, uint64_t, struct value *);

struct value *mkblock(char *);
struct value *mkglobal(char *, _Bool);
struct value *mkintconst(struct representation *, uint64_t);
struct value *mkintconst(struct repr *, uint64_t);

uint64_t intconstvalue(struct value *);

struct function *mkfunc(char *, struct type *, struct scope *);
struct type *functype(struct function *);
void funclabel(struct function *, struct value *);
struct value *funcexpr(struct function *, struct expression *);
void funcjmp(struct function *, struct value *);
void funcjnz(struct function *, struct value *, struct value *, struct value *);
void funcret(struct function *, struct value *);
struct gotolabel *funcgoto(struct function *, char *);
void funcswitch(struct function *, struct value *, struct switchcases *, struct value *);
void funcinit(struct function *, struct declaration *, struct initializer *);

void emitfunc(struct function *, _Bool);
void emitdata(struct declaration *,  struct initializer *);

extern struct representation i8, i16, i32, i64, f32, f64;
struct func *mkfunc(char *, struct type *, struct scope *);
struct type *functype(struct func *);
void funclabel(struct func *, struct value *);
struct value *funcexpr(struct func *, struct expr *);
void funcjmp(struct func *, struct value *);
void funcjnz(struct func *, struct value *, struct value *, struct value *);
void funcret(struct func *, struct value *);
struct gotolabel *funcgoto(struct func *, char *);
void funcswitch(struct func *, struct value *, struct switchcases *, struct value *);
void funcinit(struct func *, struct decl *, struct init *);

void emitfunc(struct func *, _Bool);
void emitdata(struct decl *,  struct init *);

extern struct repr i8, i16, i32, i64, f32, f64;

M decl.c => decl.c +31 -31
@@ 31,7 31,7 @@ enum storageclass {
	SCTHREADLOCAL = 1<<6,
};

enum typespecifier {
enum typespec {
	SPECNONE,

	SPECVOID     = 1<<1,


@@ 50,17 50,17 @@ enum typespecifier {
	SPECLONGLONG = SPECLONG|SPECLONG2,
};

enum funcspecifier {
enum funcspec {
	FUNCNONE,

	FUNCINLINE   = 1<<1,
	FUNCNORETURN = 1<<2,
};

struct declaration *
mkdecl(enum declarationkind k, struct type *t, enum linkage linkage)
struct decl *
mkdecl(enum declkind k, struct type *t, enum linkage linkage)
{
	struct declaration *d;
	struct decl *d;

	d = xmalloc(sizeof(*d));
	d->kind = k;


@@ 108,7 108,7 @@ storageclass(enum storageclass *sc)

/* 6.7.3 Type qualifiers */
static int
typequal(enum typequalifier *tq)
typequal(enum typequal *tq)
{
	switch (tok.kind) {
	case TCONST:    *tq |= QUALCONST;    break;


@@ 124,9 124,9 @@ typequal(enum typequalifier *tq)

/* 6.7.4 Function specifiers */
static int
funcspec(enum funcspecifier *fs)
funcspec(enum funcspec *fs)
{
	enum funcspecifier new;
	enum funcspec new;

	switch (tok.kind) {
	case TINLINE:    new = FUNCINLINE;   break;


@@ 149,7 149,7 @@ tagspec(struct scope *s)
	struct type *t;
	char *tag;
	enum typekind kind;
	struct declaration *d;
	struct decl *d;
	struct member **end;
	uint64_t i;



@@ 226,12 226,12 @@ tagspec(struct scope *s)

/* 6.7 Declarations */
static struct type *
declspecs(struct scope *s, enum storageclass *sc, enum funcspecifier *fs, int *align)
declspecs(struct scope *s, enum storageclass *sc, enum funcspec *fs, int *align)
{
	struct type *t;
	struct declaration *d;
	enum typespecifier ts = SPECNONE;
	enum typequalifier tq = QUALNONE;
	struct decl *d;
	enum typespec ts = SPECNONE;
	enum typequal tq = QUALNONE;
	int ntypes = 0;
	uint64_t i;



@@ 401,7 401,7 @@ done:
}

/* 6.7.6 Declarators */
static struct parameter *parameter(struct scope *);
static struct param *parameter(struct scope *);

struct partialtype {
	struct type *outer;


@@ 411,7 411,7 @@ struct partialtype {
static bool
istypename(struct scope *s, const char *name)
{
	struct declaration *d;
	struct decl *d;

	d = scopegetdecl(s, name, 1);
	return d && d->kind == DECLTYPE;


@@ 422,9 422,9 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs
{
	struct list *ptr;
	struct type *t;
	struct parameter **p;
	struct param **p;
	uint64_t i;
	enum typequalifier tq;
	enum typequal tq;

	while (consume(TMUL)) {
		t = mkpointertype(NULL);


@@ 577,7 577,7 @@ declarator(struct scope *s, struct type *base, char **name, bool allowabstract)
static struct type *
adjust(struct type *t)
{
	enum typequalifier tq = QUALNONE;
	enum typequal tq = QUALNONE;

	t = typeunqual(t, &tq);
	switch (t->kind) {


@@ 592,10 592,10 @@ adjust(struct type *t)
	return t;
}

static struct parameter *
static struct param *
parameter(struct scope *s)
{
	struct parameter *p;
	struct param *p;
	struct type *t;
	enum storageclass sc;



@@ 611,9 611,9 @@ parameter(struct scope *s)
}

static bool
paramdecl(struct scope *s, struct parameter *params)
paramdecl(struct scope *s, struct param *params)
{
	struct parameter *p;
	struct param *p;
	struct type *t, *base;
	char *name;



@@ 708,17 708,17 @@ typename(struct scope *s)
}

bool
decl(struct scope *s, struct function *f)
decl(struct scope *s, struct func *f)
{
	struct type *t, *base;
	enum storageclass sc;
	enum funcspecifier fs;
	struct initializer *init;
	struct parameter *p;
	enum funcspec fs;
	struct init *init;
	struct param *p;
	char *name;
	int allowfunc = !f;
	struct declaration *d;
	enum declarationkind kind;
	struct decl *d;
	enum declkind kind;
	enum linkage linkage;
	uint64_t c;
	int align;


@@ 892,12 892,12 @@ decl(struct scope *s, struct function *f)
	}
}

struct declaration *stringdecl(struct expression *expr)
struct decl *stringdecl(struct expr *expr)
{
	static struct hashtable *strings;
	struct hashtablekey key;
	void **entry;
	struct declaration *d;
	struct decl *d;

	if (!strings)
		strings = mkhtab(64);


@@ 920,5 920,5 @@ emittentativedefns(void)
	struct list *l;

	for (l = tentativedefns.next; l != &tentativedefns; l = l->next)
		emitdata(listelement(l, struct declaration, link), NULL);
		emitdata(listelement(l, struct decl, link), NULL);
}

M decl.h => decl.h +8 -8
@@ 1,4 1,4 @@
enum declarationkind {
enum declkind {
	DECLTYPE,
	DECLOBJECT,
	DECLFUNC,


@@ 25,8 25,8 @@ enum builtinkind {
	BUILTINVASTART,
};

struct declaration {
	enum declarationkind kind;
struct decl {
	enum declkind kind;
	enum linkage linkage;
	struct type *type;
	struct value *value;


@@ 41,13 41,13 @@ struct declaration {
};

struct scope;
struct function;
struct func;

struct declaration *mkdecl(enum declarationkind, struct type *, enum linkage);
_Bool decl(struct scope *, struct function *);
struct decl *mkdecl(enum declkind, struct type *, enum linkage);
_Bool decl(struct scope *, struct func *);
struct type *typename(struct scope *);

struct expression;
struct declaration *stringdecl(struct expression *);
struct expr;
struct decl *stringdecl(struct expr *);

void emittentativedefns(void);

M eval.c => eval.c +5 -5
@@ 10,7 10,7 @@
#include "type.h"

static void
binary(struct expression *expr, enum tokenkind op, struct expression *l, struct expression *r)
binary(struct expr *expr, enum tokenkind op, struct expr *l, struct expr *r)
{
	expr->kind = EXPRCONST;
#define F (1<<8)


@@ 69,11 69,11 @@ binary(struct expression *expr, enum tokenkind op, struct expression *l, struct 
#undef S
}

struct expression *
eval(struct expression *expr)
struct expr *
eval(struct expr *expr)
{
	struct expression *l, *r, *c;
	struct declaration *d;
	struct expr *l, *r, *c;
	struct decl *d;

	switch (expr->kind) {
	case EXPRIDENT:

M eval.h => eval.h +1 -1
@@ 1,1 1,1 @@
struct expression *eval(struct expression *);
struct expr *eval(struct expr *);

M expr.c => expr.c +49 -49
@@ 17,10 17,10 @@
#include "token.h"
#include "type.h"

static struct expression *
mkexpr(enum expressionkind k, struct type *t, enum expressionflags flags)
static struct expr *
mkexpr(enum exprkind k, struct type *t, enum exprflags flags)
{
	struct expression *e;
	struct expr *e;

	e = xmalloc(sizeof(*e));
	e->type = flags & EXPRFLAG_LVAL || !t ? t : typeunqual(t, NULL);


@@ 31,10 31,10 @@ mkexpr(enum expressionkind k, struct type *t, enum expressionflags flags)
	return e;
}

static struct expression *
static struct expr *
mkconstexpr(struct type *t, uint64_t n)
{
	struct expression *e;
	struct expr *e;

	e = mkexpr(EXPRCONST, t, 0);
	e->constant.i = n;


@@ 43,19 43,19 @@ mkconstexpr(struct type *t, uint64_t n)
}

void
delexpr(struct expression *e)
delexpr(struct expr *e)
{
	free(e);
}

static struct expression *mkunaryexpr(enum tokenkind, struct expression *);
static struct expr *mkunaryexpr(enum tokenkind, struct expr *);

/* 6.3.2.1 Conversion of arrays and function designators */
static struct expression *
decay(struct expression *e)
static struct expr *
decay(struct expr *e)
{
	struct type *t;
	enum typequalifier tq = QUALNONE;
	enum typequal tq = QUALNONE;

	// XXX: combine with decl.c:adjust in some way?
	t = typeunqual(e->type, &tq);


@@ 75,16 75,16 @@ decay(struct expression *e)
}

static void
lvalueconvert(struct expression *e)
lvalueconvert(struct expr *e)
{
	e->type = typeunqual(e->type, NULL);
	e->flags &= ~EXPRFLAG_LVAL;
}

static struct expression *
mkunaryexpr(enum tokenkind op, struct expression *base)
static struct expr *
mkunaryexpr(enum tokenkind op, struct expr *base)
{
	struct expression *expr;
	struct expr *expr;

	switch (op) {
	case TBAND:


@@ 110,7 110,7 @@ mkunaryexpr(enum tokenkind op, struct expression *base)
}

static struct type *
commonreal(struct expression **e1, struct expression **e2)
commonreal(struct expr **e1, struct expr **e2)
{
	struct type *t;



@@ 121,12 121,12 @@ commonreal(struct expression **e1, struct expression **e2)
	return t;
}

static struct expression *
mkbinaryexpr(struct location *loc, enum tokenkind op, struct expression *l, struct expression *r)
static struct expr *
mkbinaryexpr(struct location *loc, enum tokenkind op, struct expr *l, struct expr *r)
{
	struct expression *e;
	struct expr *e;
	struct type *t = NULL;
	enum typeproperty lp, rp;
	enum typeprop lp, rp;

	lvalueconvert(l);
	lvalueconvert(r);


@@ 316,11 316,11 @@ unescape(char **p)
}

/* 6.5 Expressions */
static struct expression *
static struct expr *
primaryexpr(struct scope *s)
{
	struct expression *e;
	struct declaration *d;
	struct expr *e;
	struct decl *d;
	char *src, *dst, *end;
	int base;



@@ 405,12 405,12 @@ primaryexpr(struct scope *s)
	return e;
}

static struct expression *condexpr(struct scope *);
static struct expr *condexpr(struct scope *);

static struct expression *
static struct expr *
builtinfunc(struct scope *s, enum builtinkind kind)
{
	struct expression *e;
	struct expr *e;
	struct type *t;
	char *name;
	uint64_t offset;


@@ 483,13 483,13 @@ builtinfunc(struct scope *s, enum builtinkind kind)
	return e;
}

static struct expression *
postfixexpr(struct scope *s, struct expression *r)
static struct expr *
postfixexpr(struct scope *s, struct expr *r)
{
	struct expression *e, *arr, *idx, *tmp, **end;
	struct expr *e, *arr, *idx, *tmp, **end;
	struct type *t;
	enum typequalifier tq;
	struct parameter *p;
	enum typequal tq;
	struct param *p;
	uint64_t offset;
	enum tokenkind op;
	bool lvalue;


@@ 601,13 601,13 @@ postfixexpr(struct scope *s, struct expression *r)
	}
}

static struct expression *castexpr(struct scope *);
static struct expr *castexpr(struct scope *);

static struct expression *
static struct expr *
unaryexpr(struct scope *s)
{
	enum tokenkind op;
	struct expression *e, *l;
	struct expr *e, *l;
	struct type *t;

	op = tok.kind;


@@ 695,11 695,11 @@ unaryexpr(struct scope *s)
	return e;
}

static struct expression *
static struct expr *
castexpr(struct scope *s)
{
	struct type *t;
	struct expression *r, *e, **end;
	struct expr *r, *e, **end;

	end = &r;
	while (consume(TLPAREN)) {


@@ 758,7 758,7 @@ ismultiplicative(enum tokenkind t)
	return t == TMUL || t == TDIV || t == TMOD;
}

static struct expression *
static struct expr *
binaryexpr(struct scope *s, size_t i)
{
	static const struct {


@@ 777,7 777,7 @@ binaryexpr(struct scope *s, size_t i)
		{.fn = isadditive},
		{.fn = ismultiplicative},
	};
	struct expression *e, *l, *r;
	struct expr *e, *l, *r;
	struct location loc;
	enum tokenkind op;



@@ 797,7 797,7 @@ binaryexpr(struct scope *s, size_t i)
}

static bool
nullpointer(struct expression *e)
nullpointer(struct expr *e)
{
	if (e->kind != EXPRCONST)
		return false;


@@ 806,12 806,12 @@ nullpointer(struct expression *e)
	return e->constant.i == 0;
}

static struct expression *
static struct expr *
condexpr(struct scope *s)
{
	struct expression *r, *e;
	struct expr *r, *e;
	struct type *t, *f;
	enum typequalifier tq;
	enum typequal tq;

	r = binaryexpr(s, 0);
	if (!consume(TQUESTION))


@@ 861,7 861,7 @@ condexpr(struct scope *s)
uint64_t
intconstexpr(struct scope *s, bool allowneg)
{
	struct expression *e;
	struct expr *e;

	e = eval(condexpr(s));
	if (e->kind != EXPRCONST || !(typeprop(e->type) & PROPINT))


@@ 871,10 871,10 @@ intconstexpr(struct scope *s, bool allowneg)
	return e->constant.i;
}

struct expression *
struct expr *
assignexpr(struct scope *s)
{
	struct expression *e, *l, *r, *tmp = NULL, **res = &e;
	struct expr *e, *l, *r, *tmp = NULL, **res = &e;
	enum tokenkind op;

	l = condexpr(s);


@@ 920,10 920,10 @@ assignexpr(struct scope *s)
	return e;
}

struct expression *
struct expr *
expr(struct scope *s)
{
	struct expression *r, *e, **end;
	struct expr *r, *e, **end;

	end = &r;
	for (;;) {


@@ 942,10 942,10 @@ expr(struct scope *s)
	return e;
}

struct expression *
exprconvert(struct expression *e, struct type *t)
struct expr *
exprconvert(struct expr *e, struct type *t)
{
	struct expression *cast;
	struct expr *cast;

	if (typecompatible(e->type, t))
		return e;

M expr.h => expr.h +21 -21
@@ 1,4 1,4 @@
enum expressionkind {
enum exprkind {
	/* primary expression */
	EXPRIDENT,
	EXPRCONST,


@@ 22,19 22,19 @@ enum expressionkind {
	EXPRTEMP,
};

enum expressionflags {
enum exprflags {
	EXPRFLAG_LVAL    = 1<<0,
	EXPRFLAG_DECAYED = 1<<1,
};

struct expression {
	enum expressionkind kind;
	enum expressionflags flags;
struct expr {
	enum exprkind kind;
	enum exprflags flags;
	struct type *type;
	struct expression *next;
	struct expr *next;
	union {
		struct {
			struct declaration *decl;
			struct decl *decl;
		} ident;
		union {
			uint64_t i;


@@ 45,40 45,40 @@ struct expression {
			size_t size;
		} string;
		struct {
			struct expression *func, *args;
			struct expr *func, *args;
			size_t nargs;
		} call;
		struct {
			struct initializer *init;
			struct init *init;
		} compound;
		struct {
			int op;
			_Bool post;
			struct expression *base;
			struct expr *base;
		} incdec;
		struct {
			int op;
			struct expression *base;
			struct expr *base;
		} unary;
		struct {
			struct expression *e;
			struct expr *e;
		} cast;
		struct {
			int op;
			struct expression *l, *r;
			struct expr *l, *r;
		} binary;
		struct {
			struct expression *e, *t, *f;
			struct expr *e, *t, *f;
		} cond;
		struct {
			struct expression *l, *r;
			struct expr *l, *r;
		} assign;
		struct {
			struct expression *exprs;
			struct expr *exprs;
		} comma;
		struct {
			int kind;
			struct expression *arg;
			struct expr *arg;
		} builtin;
		struct value *temp;
	};


@@ 86,9 86,9 @@ struct expression {

struct scope;

struct expression *expr(struct scope *);
struct expression *assignexpr(struct scope *);
struct expr *expr(struct scope *);
struct expr *assignexpr(struct scope *);
uint64_t intconstexpr(struct scope *, _Bool);
void delexpr(struct expression *);
void delexpr(struct expr *);

struct expression *exprconvert(struct expression *, struct type *);
struct expr *exprconvert(struct expr *, struct type *);

M init.c => init.c +8 -8
@@ 29,10 29,10 @@ struct initparser {
	struct object obj[32], *cur, *sub;
};

struct initializer *
mkinit(uint64_t start, uint64_t end, struct expression *expr)
struct init *
mkinit(uint64_t start, uint64_t end, struct expr *expr)
{
	struct initializer *init;
	struct init *init;

	init = xmalloc(sizeof(*init));
	init->start = start;


@@ 44,9 44,9 @@ mkinit(uint64_t start, uint64_t end, struct expression *expr)
}

static void
initadd(struct initializer **init, struct initializer *new)
initadd(struct init **init, struct init *new)
{
	struct initializer *next, *sub, *last;
	struct init *next, *sub, *last;
	uint64_t offset;

	while (*init && new->start >= (*init)->end)


@@ 208,12 208,12 @@ advance(struct initparser *p)
}

/* 6.7.9 Initialization */
struct initializer *
struct init *
parseinit(struct scope *s, struct type *t)
{
	struct initparser p;
	struct initializer *init = NULL;
	struct expression *expr;
	struct init *init = NULL;
	struct expr *expr;
	struct type *base;

	t = typeunqual(t, NULL);

M init.h => init.h +5 -7
@@ 1,13 1,11 @@
struct initializer {
struct init {
	uint64_t start, end;
	struct expression *expr;
	struct initializer *next, *subinit;
	struct expr *expr;
	struct init *next, *subinit;
};

struct scope;
struct type;
struct function;
struct declaration;

struct initializer *mkinit(uint64_t, uint64_t, struct expression *);
struct initializer *parseinit(struct scope *, struct type *);
struct init *mkinit(uint64_t, uint64_t, struct expr *);
struct init *parseinit(struct scope *, struct type *);

M qbe.c => qbe.c +65 -65
@@ 22,7 22,7 @@ struct name {
	uint64_t id;
};

struct representation {
struct repr {
	char base;
	char ext;
	struct name abi;


@@ 36,7 36,7 @@ struct value {
		VALLABEL,
		VALTEMP,
	} kind;
	struct representation *repr;
	struct repr *repr;
	union {
		struct name name;
		uint64_t i;


@@ 44,7 44,7 @@ struct value {
	};
};

enum instructionkind {
enum instkind {
	INONE,

#define OP(op, ret, arg, name) op,


@@ 52,8 52,8 @@ enum instructionkind {
#undef OP
};

struct instruction {
	enum instructionkind kind;
struct inst {
	enum instkind kind;
	struct value res, *arg[];
};



@@ 70,22 70,22 @@ struct switchcase {
	struct value *body;
};

struct function {
struct func {
	char *name;
	struct declaration *namedecl;
	struct decl *namedecl;
	struct type *type;
	struct block *start, *end;
	struct hashtable *gotos;
	uint64_t lastid;
};

struct representation i8 = {'w', 'b'};
struct representation i16 = {'w', 'h'};
struct representation i32 = {'w', 'w'};
struct representation i64 = {'l', 'l'};
struct representation f32 = {'s', 's'};
struct representation f64 = {'d', 'd'};
struct representation iptr = {'l', 'l'};
struct repr i8 = {'w', 'b'};
struct repr i16 = {'w', 'h'};
struct repr i32 = {'w', 'w'};
struct repr i64 = {'l', 'l'};
struct repr f32 = {'s', 's'};
struct repr f64 = {'d', 'd'};
struct repr iptr = {'l', 'l'};

void
switchcase(struct switchcases *cases, uint64_t i, struct value *v)


@@ 121,14 121,14 @@ static void emittype(struct type *);
static void emitvalue(struct value *);

static void
funcname(struct function *f, struct name *n, char *s)
funcname(struct func *f, struct name *n, char *s)
{
	n->id = ++f->lastid;
	n->str = s;
}

static void
functemp(struct function *f, struct value *v, struct representation *repr)
functemp(struct func *f, struct value *v, struct repr *repr)
{
	if (!repr)
		fatal("temp has no type");


@@ 147,9 147,9 @@ static struct {
};

static struct value *
funcinstn(struct function *f, int op, struct representation *repr, struct value *args[])
funcinstn(struct func *f, int op, struct repr *repr, struct value *args[])
{
	struct instruction *inst;
	struct inst *inst;
	size_t n;

	if (f->end->terminated)


@@ 179,7 179,7 @@ funcinstn(struct function *f, int op, struct representation *repr, struct value 
#define funcinst(f, op, repr, ...) funcinstn(f, op, repr, (struct value *[]){__VA_ARGS__})

struct value *
mkintconst(struct representation *r, uint64_t n)
mkintconst(struct repr *r, uint64_t n)
{
	struct value *v;



@@ 199,7 199,7 @@ intconstvalue(struct value *v)
}

static struct value *
mkfltconst(struct representation *r, double n)
mkfltconst(struct repr *r, double n)
{
	struct value *v;



@@ 212,10 212,10 @@ mkfltconst(struct representation *r, double n)
}

static void
funcalloc(struct function *f, struct declaration *d)
funcalloc(struct func *f, struct decl *d)
{
	enum instructionkind op;
	struct instruction *inst;
	enum instkind op;
	struct inst *inst;

	assert(!d->type->incomplete);
	assert(d->type->size > 0);


@@ 241,10 241,10 @@ funcalloc(struct function *f, struct declaration *d)
}

static void
funcstore(struct function *f, struct type *t, struct value *addr, struct value *v)
funcstore(struct func *f, struct type *t, struct value *addr, struct value *v)
{
	enum instructionkind op;
	enum typequalifier tq = QUALNONE;
	enum instkind op;
	enum typequal tq = QUALNONE;

	t = typeunqual(t, &tq);
	if (tq & QUALVOLATILE)


@@ 268,7 268,7 @@ funcstore(struct function *f, struct type *t, struct value *addr, struct value *
	case TYPESTRUCT:
	case TYPEUNION:
	case TYPEARRAY: {
		enum instructionkind loadop, op;
		enum instkind loadop, op;
		struct value *src, *dst, *tmp, *align;
		uint64_t offset;



@@ 298,11 298,11 @@ funcstore(struct function *f, struct type *t, struct value *addr, struct value *
}

static struct value *
funcload(struct function *f, struct type *t, struct value *addr)
funcload(struct func *f, struct type *t, struct value *addr)
{
	struct value *v;
	enum instructionkind op;
	enum typequalifier tq;
	enum instkind op;
	enum typequal tq;

	t = typeunqual(t, &tq);
	switch (t->kind) {


@@ 353,12 353,12 @@ parameter affected by default argument promotion, we need to emit a QBE
function with the promoted type and implicitly convert to the declared
parameter type before storing into the allocated memory for the parameter.
*/
struct function *
struct func *
mkfunc(char *name, struct type *t, struct scope *s)
{
	struct function *f;
	struct parameter *p;
	struct declaration *d;
	struct func *f;
	struct param *p;
	struct decl *d;

	f = xmalloc(sizeof(*f));
	f->name = name;


@@ 406,13 406,13 @@ mkfunc(char *name, struct type *t, struct scope *s)
}

struct type *
functype(struct function *f)
functype(struct func *f)
{
	return f->type;
}

void
funclabel(struct function *f, struct value *v)
funclabel(struct func *f, struct value *v)
{
	assert(v->kind == VALLABEL);
	f->end->next = (struct block *)v;


@@ 420,28 420,28 @@ funclabel(struct function *f, struct value *v)
}

void
funcjmp(struct function *f, struct value *v)
funcjmp(struct func *f, struct value *v)
{
	funcinst(f, IJMP, NULL, v);
	f->end->terminated = true;
}

void
funcjnz(struct function *f, struct value *v, struct value *l1, struct value *l2)
funcjnz(struct func *f, struct value *v, struct value *l1, struct value *l2)
{
	funcinst(f, IJNZ, NULL, v, l1, l2);
	f->end->terminated = true;
}

void
funcret(struct function *f, struct value *v)
funcret(struct func *f, struct value *v)
{
	funcinst(f, IRET, NULL, v);
	f->end->terminated = true;
}

struct gotolabel *
funcgoto(struct function *f, char *name)
funcgoto(struct func *f, char *name)
{
	void **entry;
	struct gotolabel *g;


@@ 460,9 460,9 @@ funcgoto(struct function *f, char *name)
}

static struct value *
objectaddr(struct function *f, struct expression *e)
objectaddr(struct func *f, struct expr *e)
{
	struct declaration *d;
	struct decl *d;

	switch (e->kind) {
	case EXPRIDENT:


@@ 497,7 497,7 @@ objectaddr(struct function *f, struct expression *e)

/* TODO: move these conversions to QBE */
static struct value *
utof(struct function *f, struct representation *r, struct value *v)
utof(struct func *f, struct repr *r, struct value *v)
{
	struct value *odd, *big, *phi[5] = {0}, *join;



@@ 529,10 529,10 @@ utof(struct function *f, struct representation *r, struct value *v)
}

static struct value *
ftou(struct function *f, struct representation *r, struct value *v)
ftou(struct func *f, struct repr *r, struct value *v)
{
	struct value *big, *phi[5] = {0}, *join, *maxflt, *maxint;
	enum instructionkind op = v->repr->base == 's' ? ISTOSI : IDTOSI;
	enum instkind op = v->repr->base == 's' ? ISTOSI : IDTOSI;

	if (r->base == 'w') {
		v = funcinst(f, op, &i64, v);


@@ 563,9 563,9 @@ ftou(struct function *f, struct representation *r, struct value *v)
}

static struct value *
extend(struct function *f, struct type *t, struct value *v)
extend(struct func *f, struct type *t, struct value *v)
{
	enum instructionkind op;
	enum instkind op;

	switch (t->size) {
	case 1: op = t->basic.issigned ? IEXTSB : IEXTUB; break;


@@ 576,12 576,12 @@ extend(struct function *f, struct type *t, struct value *v)
}

struct value *
funcexpr(struct function *f, struct expression *e)
funcexpr(struct func *f, struct expr *e)
{
	enum instructionkind op = INONE;
	struct declaration *d;
	enum instkind op = INONE;
	struct decl *d;
	struct value *l, *r, *v, *addr, **argvals, **argval;
	struct expression *arg;
	struct expr *arg;
	struct value *label[5];
	struct type *t;



@@ 865,9 865,9 @@ funcexpr(struct function *f, struct expression *e)
}

static void
zero(struct function *func, struct value *addr, int align, uint64_t offset, uint64_t end)
zero(struct func *func, struct value *addr, int align, uint64_t offset, uint64_t end)
{
	enum instructionkind store[] = {
	enum instkind store[] = {
		[1] = ISTOREB,
		[2] = ISTOREH,
		[4] = ISTOREW,


@@ 889,7 889,7 @@ zero(struct function *func, struct value *addr, int align, uint64_t offset, uint
}

void
funcinit(struct function *func, struct declaration *d, struct initializer *init)
funcinit(struct func *func, struct decl *d, struct init *init)
{
	struct value *src, *dst;
	uint64_t offset = 0;


@@ 917,7 917,7 @@ funcinit(struct function *func, struct declaration *d, struct initializer *init)
}

static void
casesearch(struct function *f, struct value *v, struct switchcase *c, struct value *defaultlabel)
casesearch(struct func *f, struct value *v, struct switchcase *c, struct value *defaultlabel)
{
	struct value *res, *label[3], *key;



@@ 943,7 943,7 @@ casesearch(struct function *f, struct value *v, struct switchcase *c, struct val
}

void
funcswitch(struct function *f, struct value *v, struct switchcases *c, struct value *defaultlabel)
funcswitch(struct func *f, struct value *v, struct switchcases *c, struct value *defaultlabel)
{
	casesearch(f, v, c->root, defaultlabel);
}


@@ 986,7 986,7 @@ emitvalue(struct value *v)
}

static void
emitrepr(struct representation *r, bool abi, bool ext)
emitrepr(struct repr *r, bool abi, bool ext)
{
	if (abi && r->abi.id) {
		putchar(':');


@@ 1038,7 1038,7 @@ emittype(struct type *t)
}

static void
emitinst(struct instruction *inst)
emitinst(struct inst *inst)
{
	struct value **arg;



@@ 1098,11 1098,11 @@ emitinst(struct instruction *inst)
}

void
emitfunc(struct function *f, bool global)
emitfunc(struct func *f, bool global)
{
	struct block *b;
	struct instruction **inst;
	struct parameter *p;
	struct inst **inst;
	struct param *p;
	size_t n;

	if (!f->end->terminated)


@@ 1136,9 1136,9 @@ emitfunc(struct function *f, bool global)
}

static void
dataitem(struct expression *expr, uint64_t size)
dataitem(struct expr *expr, uint64_t size)
{
	struct declaration *decl;
	struct decl *decl;
	size_t i;
	char c;



@@ 1186,10 1186,10 @@ dataitem(struct expression *expr, uint64_t size)
}

void
emitdata(struct declaration *d, struct initializer *init)
emitdata(struct decl *d, struct init *init)
{
	uint64_t offset = 0;
	struct initializer *cur;
	struct init *cur;

	if (!d->align)
		d->align = d->type->align;

M scope.c => scope.c +4 -4
@@ 15,7 15,7 @@ scopeinit(void)
{
	static struct builtin {
		char *name;
		struct declaration decl;
		struct decl decl;
	} builtins[] = {
		{"__builtin_alloca",     {.kind = DECLBUILTIN, .builtin = BUILTINALLOCA}},
		{"__builtin_constant_p", {.kind = DECLBUILTIN, .builtin = BUILTINCONSTANTP}},


@@ 64,10 64,10 @@ delscope(struct scope *s)
	return parent;
}

struct declaration *
struct decl *
scopegetdecl(struct scope *s, const char *name, bool recurse)
{
	struct declaration *d;
	struct decl *d;
	struct hashtablekey k;

	htabstrkey(&k, name);


@@ 95,7 95,7 @@ scopegettag(struct scope *s, const char *name, bool recurse)
}

void
scopeputdecl(struct scope *s, const char *name, struct declaration *d)
scopeputdecl(struct scope *s, const char *name, struct decl *d)
{
	struct hashtablekey k;


M scope.h => scope.h +3 -3
@@ 11,9 11,9 @@ void scopeinit(void);
struct scope *mkscope(struct scope *);
struct scope *delscope(struct scope *);

struct declaration;
void scopeputdecl(struct scope *, const char *, struct declaration *);
struct declaration *scopegetdecl(struct scope *, const char *, _Bool);
struct decl;
void scopeputdecl(struct scope *, const char *, struct decl *);
struct decl *scopegetdecl(struct scope *, const char *, _Bool);

struct type;
void scopeputtag(struct scope *, const char *, struct type *);

M stmt.c => stmt.c +4 -4
@@ 15,7 15,7 @@
#include "type.h"

static bool
gotolabel(struct function *f)
gotolabel(struct func *f)
{
	char *name;
	struct gotolabel *g;


@@ 33,10 33,10 @@ gotolabel(struct function *f)

/* 6.8 Statements and blocks */
void
stmt(struct function *f, struct scope *s)
stmt(struct func *f, struct scope *s)
{
	char *name;
	struct expression *e;
	struct expr *e;
	struct type *t;
	struct value *v, *label[4];
	struct switchcases swtch = {0};


@@ 54,7 54,7 @@ stmt(struct function *f, struct scope *s)
		funclabel(f, label[0]);
		i = intconstexpr(s, true);
		switchcase(s->switchcases, i, label[0]);
		expect(TCOLON, "after case expression");
		expect(TCOLON, "after case expr");
		stmt(f, s);
		break;
	case TDEFAULT:

M stmt.h => stmt.h +2 -2
@@ 1,4 1,4 @@
struct function;
struct func;
struct scope;

void stmt(struct function *, struct scope *);
void stmt(struct func *, struct scope *);

M type.c => type.c +7 -7
@@ 47,7 47,7 @@ mktype(enum typekind kind)
}

struct type *
mkqualifiedtype(struct type *base, enum typequalifier tq)
mkqualifiedtype(struct type *base, enum typequal tq)
{
	struct type *t;



@@ 96,10 96,10 @@ mkarraytype(struct type *base, uint64_t len)
	return t;
}

enum typeproperty
enum typeprop
typeprop(struct type *t)
{
	enum typeproperty p = PROPNONE;
	enum typeprop p = PROPNONE;

	switch (t->kind) {
	case TYPEVOID:


@@ 163,7 163,7 @@ bool
typecompatible(struct type *t1, struct type *t2)
{
	struct type *tmp;
	struct parameter *p1, *p2;
	struct param *p1, *p2;

	if (t1 == t2)
		return true;


@@ 232,7 232,7 @@ typecomposite(struct type *t1, struct type *t2)
}

struct type *
typeunqual(struct type *t, enum typequalifier *tq)
typeunqual(struct type *t, enum typequal *tq)
{
	while (t->kind == TYPEQUALIFIED) {
		if (tq)


@@ 319,10 319,10 @@ typemember(struct type *t, const char *name, uint64_t *offset)
	return NULL;
}

struct parameter *
struct param *
mkparam(char *name, struct type *t)
{
	struct parameter *p;
	struct param *p;

	p = xmalloc(sizeof(*p));
	p->name = name;

M type.h => type.h +11 -11
@@ 1,4 1,4 @@
enum typequalifier {
enum typequal {
	QUALNONE,

	QUALCONST    = 1<<1,


@@ 20,7 20,7 @@ enum typekind {
	TYPEUNION,
};

enum typeproperty {
enum typeprop {
	PROPNONE,

	PROPOBJECT  = 1<<0,


@@ 34,11 34,11 @@ enum typeproperty {
	PROPFLOAT   = 1<<8,
};

struct parameter {
struct param {
	char *name;
	struct type *type;
	struct value *value;
	struct parameter *next;
	struct param *next;
};

struct member {


@@ 52,7 52,7 @@ struct type {
	enum typekind kind;
	int align;
	uint64_t size;
	struct representation *repr;
	struct repr *repr;
	union {
		struct type *base;
		struct list link;  /* used only during construction of type */


@@ 60,7 60,7 @@ struct type {
	_Bool incomplete;
	union {
		struct {
			enum typequalifier kind;
			enum typequal kind;
		} qualified;
		struct {
			enum {


@@ 82,7 82,7 @@ struct type {
		} array;
		struct {
			_Bool isprototype, isvararg, isnoreturn, paraminfo;
			struct parameter *params;
			struct param *params;
		} func;
		struct {
			char *tag;


@@ 92,21 92,21 @@ struct type {
};

struct type *mktype(enum typekind);
struct type *mkqualifiedtype(struct type *, enum typequalifier);
struct type *mkqualifiedtype(struct type *, enum typequal);
struct type *mkpointertype(struct type *);
struct type *mkarraytype(struct type *, uint64_t);

_Bool typecompatible(struct type *, struct type *);
_Bool typesame(struct type *, struct type *);
struct type *typecomposite(struct type *, struct type *);
struct type *typeunqual(struct type *, enum typequalifier *);
struct type *typeunqual(struct type *, enum typequal *);
struct type *typecommonreal(struct type *, struct type *);
struct type *typeargpromote(struct type *);
struct type *typeintpromote(struct type *);
enum typeproperty typeprop(struct type *);
enum typeprop typeprop(struct type *);
struct type *typemember(struct type *, const char *, uint64_t *);

struct parameter *mkparam(char *, struct type *);
struct param *mkparam(char *, struct type *);

extern struct type typevoid;
extern struct type typebool;