aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2024-04-12 00:58:35 -0700
committerMichael Forney <mforney@mforney.org>2024-04-12 01:03:04 -0700
commit053705b0ebc25a355c10ea46b3df18a84a5b842e (patch)
treec8e59307bd5b25f5ff210676ab2466d81d905a70
parent7d6efdd8626fd3a654a8f231fc1ddc481352af6a (diff)
Use struct decl for function parameters
-rw-r--r--cc.h12
-rw-r--r--decl.c21
-rw-r--r--expr.c2
-rw-r--r--qbe.c29
-rw-r--r--type.c16
5 files changed, 28 insertions, 52 deletions
diff --git a/cc.h b/cc.h
index e69bad0..5e244f0 100644
--- a/cc.h
+++ b/cc.h
@@ -181,14 +181,6 @@ enum typeprop {
PROPFLOAT = 1<<5
};
-struct param {
- char *name;
- struct type *type;
- enum typequal qual;
- struct value *value;
- struct param *next;
-};
-
struct bitfield {
short before; /* number of bits in the storage unit before the bit-field */
short after; /* number of bits in the storage unit after the bit-field */
@@ -224,7 +216,7 @@ struct type {
} array;
struct {
bool isprototype, isvararg, isnoreturn, paraminfo;
- struct param *params;
+ struct decl *params;
size_t nparam;
} func;
struct {
@@ -443,8 +435,6 @@ enum typeprop typeprop(struct type *);
struct member *typemember(struct type *, const char *, unsigned long long *);
bool typehasint(struct type *, unsigned long long, bool);
-struct param *mkparam(char *, struct type *, enum typequal);
-
extern struct type typevoid;
extern struct type typebool;
extern struct type typechar, typeschar, typeuchar;
diff --git a/decl.c b/decl.c
index a2b689e..655e4b9 100644
--- a/decl.c
+++ b/decl.c
@@ -71,7 +71,7 @@ mkdecl(char *name, enum declkind k, struct type *t, enum typequal tq, enum linka
d->linkage = linkage;
d->type = t;
d->qual = tq;
- if (k == DECLOBJECT)
+ if (k == DECLOBJECT && t)
d->u.obj.align = t->align;
return d;
@@ -519,7 +519,7 @@ done:
}
/* 6.7.6 Declarators */
-static struct param *parameter(struct scope *);
+static struct decl *parameter(struct scope *);
static bool
istypename(struct scope *s, const char *name)
@@ -541,7 +541,7 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs
{
struct list *ptr;
struct type *t;
- struct param **p;
+ struct decl **p;
struct expr *e;
enum typequal tq;
bool allowattr;
@@ -608,8 +608,9 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs
if (!istypename(s, tok.lit)) {
/* identifier-list (K&R declaration) */
do {
- *p = mkparam(tok.lit, NULL, QUALNONE);
+ *p = mkdecl(tok.lit, DECLOBJECT, NULL, QUALNONE, LINKNONE);
p = &(*p)->next;
+ ++t->u.func.nparam;
next();
} while (consume(TCOMMA) && tok.kind == TIDENT);
break;
@@ -720,7 +721,7 @@ declarator(struct scope *s, struct qualtype base, char **name, bool allowabstrac
return base;
}
-static struct param *
+static struct decl *
parameter(struct scope *s)
{
char *name;
@@ -735,14 +736,13 @@ parameter(struct scope *s)
error(&tok.loc, "parameter declaration has invalid storage-class specifier");
t = declarator(s, t, &name, true);
t.type = typeadjust(t.type, &t.qual);
-
- return mkparam(name, t.type, t.qual);
+ return mkdecl(name, DECLOBJECT, t.type, t.qual, LINKNONE);
}
static bool
-paramdecl(struct scope *s, struct param *params)
+paramdecl(struct scope *s, struct decl *params)
{
- struct param *p;
+ struct decl *p;
struct qualtype t, base;
enum storageclass sc;
char *name;
@@ -760,6 +760,7 @@ paramdecl(struct scope *s, struct param *params)
error(&tok.loc, "old-style function declarator has no parameter named '%s'", name);
p->type = typeadjust(t.type, &t.qual);
p->qual = t.qual;
+ p->u.obj.align = p->type->align;
if (tok.kind == TSEMICOLON)
break;
expect(TCOMMA, "or ';' after parameter declarator");
@@ -1001,7 +1002,7 @@ decl(struct scope *s, struct func *f)
enum funcspec fs;
struct init *init;
bool hasinit;
- struct param *p;
+ struct decl *p;
char *name, *asmname;
int allowfunc = !f;
struct decl *d, *prior;
diff --git a/expr.c b/expr.c
index bcf4fc7..0e7c0b4 100644
--- a/expr.c
+++ b/expr.c
@@ -902,7 +902,7 @@ postfixexpr(struct scope *s, struct expr *r)
{
struct expr *e, *arr, *idx, *tmp, **end;
struct type *t;
- struct param *p;
+ struct decl *p;
struct member *m;
unsigned long long offset;
enum typequal tq;
diff --git a/qbe.c b/qbe.c
index f4c97db..e425e58 100644
--- a/qbe.c
+++ b/qbe.c
@@ -87,6 +87,7 @@ struct switchcase {
struct func {
struct decl *decl, *namedecl;
char *name;
+ struct value *paramtemps;
struct type *type;
struct block *start, *end;
struct map gotos;
@@ -471,10 +472,9 @@ struct func *
mkfunc(struct decl *decl, char *name, struct type *t, struct scope *s)
{
struct func *f;
- struct param *p;
struct decl *d;
struct type *pt;
- struct value *v;
+ struct value *v, *pv;
f = xmalloc(sizeof(*f));
f->decl = decl;
@@ -486,20 +486,19 @@ mkfunc(struct decl *decl, char *name, struct type *t, struct scope *s)
emittype(t->base);
/* allocate space for parameters */
- for (p = t->u.func.params; p; p = p->next) {
- pt = t->u.func.isprototype ? p->type : typepromote(p->type, -1);
+ f->paramtemps = xreallocarray(NULL, t->u.func.nparam, sizeof *f->paramtemps);
+ for (d = t->u.func.params, pv = f->paramtemps; d; d = d->next, ++pv) {
+ pt = t->u.func.isprototype ? d->type : typepromote(d->type, -1);
emittype(pt);
- p->value = xmalloc(sizeof(*p->value));
- functemp(f, p->value);
- if(!p->name)
+ functemp(f, pv);
+ if(!d->name)
continue;
- d = mkdecl(p->name, DECLOBJECT, p->type, p->qual, LINKNONE);
- if (p->type->value) {
- d->value = p->value;
+ if (d->type->value) {
+ d->value = pv;
} else {
- v = typecompatible(p->type, pt) ? p->value : convert(f, pt, p->type, p->value);
+ v = typecompatible(d->type, pt) ? pv : convert(f, pt, d->type, pv);
funcalloc(f, d);
- funcstore(f, p->type, QUALNONE, (struct lvalue){d->value}, v);
+ funcstore(f, d->type, QUALNONE, (struct lvalue){d->value}, v);
}
scopeputdecl(s, d);
}
@@ -1198,7 +1197,7 @@ emitfunc(struct func *f, bool global)
{
struct block *b;
struct inst **inst, **instend;
- struct param *p;
+ struct decl *p;
struct value *v;
if (f->end->jump.kind == JUMP_NONE) {
@@ -1217,12 +1216,12 @@ emitfunc(struct func *f, bool global)
}
emitvalue(f->decl->value);
putchar('(');
- for (p = f->type->u.func.params; p; p = p->next) {
+ for (p = f->type->u.func.params, v = f->paramtemps; p; p = p->next, ++v) {
if (p != f->type->u.func.params)
fputs(", ", stdout);
emitclass(qbetype(p->type).base, p->type->value);
putchar(' ');
- emitvalue(p->value);
+ emitvalue(v);
}
if (f->type->u.func.isvararg)
fputs(", ...", stdout);
diff --git a/type.c b/type.c
index 6798105..d8c1a6a 100644
--- a/type.c
+++ b/type.c
@@ -112,7 +112,7 @@ bool
typecompatible(struct type *t1, struct type *t2)
{
struct type *tmp;
- struct param *p1, *p2;
+ struct decl *p1, *p2;
if (t1 == t2)
return true;
@@ -276,17 +276,3 @@ typehasint(struct type *t, unsigned long long i, bool sign)
return t->u.basic.issigned && i >= -1ull << (t->size << 3) - 1;
return i <= 0xffffffffffffffffull >> (8 - t->size << 3) + t->u.basic.issigned;
}
-
-struct param *
-mkparam(char *name, struct type *t, enum typequal tq)
-{
- struct param *p;
-
- p = xmalloc(sizeof(*p));
- p->name = name;
- p->type = t;
- p->qual = tq;
- p->next = NULL;
-
- return p;
-}