diff options
| author | 2022-08-18 17:39:25 +0200 | |
|---|---|---|
| committer | 2022-08-18 17:39:25 +0200 | |
| commit | 9c485da5e1d955031fa2a3654bfc2ef814898167 (patch) | |
| tree | 44e841ced0479d5ec82cca28733413784eedf52c /bootstrap/cgen.c | |
| parent | f0214ff61b5a94b9629db6f43d7a5b010bd4ffbc (diff) | |
lots of goodnes
Diffstat (limited to 'bootstrap/cgen.c')
| -rw-r--r-- | bootstrap/cgen.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c index d7b91b0..e047f08 100644 --- a/bootstrap/cgen.c +++ b/bootstrap/cgen.c @@ -730,7 +730,7 @@ gendecl(struct decl *decl, bool toplevel) { } static void -defctype(const struct type *ty, void *_) { +declctype(const struct type *ty, void *_) { static int id; char **cname = (char **)&ty->_cname; const char *kind; @@ -739,9 +739,43 @@ defctype(const struct type *ty, void *_) { switch (ty->t) { case TYvoid: case TYbool: case TYvalist: case TYenum: case TYint: case TYfloat: + case TYptr: case TYarr: case TYslice: + case TYfn: + *(bool *)&ty->_defined = 1; + break; + case TYstruct: case TYeunion: + kind = "struct"; + goto agg; + case TYunion: + kind = "union"; + agg: + if (ty->konst) { + declctype(unconstify(ty), NULL); + *cname = (char *)unconstify(ty)->_cname; + break; + } + *(bool *)&ty->_defined = 0; + *cname = xasprintf("__ta%s%d", ty->agg.name ? ty->agg.name : "", id++); + pri("typedef %s %s %s;\n", kind, *cname, *cname); + } +} + +#define isagg(ty) ((ty)->t == TYstruct || (ty)->t == TYunion || (ty)->t == TYenum) + +static void +defctype(const struct type *ty, void *_) { + static int id; + char **cname = (char **)&ty->_cname; + const char *kind; + + if (!ty->_cname || (!ty->_defined)) + switch (ty->t) { + case TYvoid: case TYbool: case TYvalist: + case TYenum: case TYint: case TYfloat: break; case TYptr: - defctype(ty->child, NULL); + if (!isagg(ty->child)) + defctype(ty->child, NULL); break; case TYarr: if (ty->length >= 0) { @@ -757,9 +791,10 @@ defctype(const struct type *ty, void *_) { *cname = (char *)ty2->_cname; return; } - defctype(ty->child, NULL); if (ty->_cname) break; *cname = xasprintf("__ty%d", id++); + if (!isagg(ty->child)) + defctype(ty->child, NULL); pri("typedef struct { %t *ptr; size_t len; } %s;\n", ty->child, *cname); @@ -789,13 +824,13 @@ defctype(const struct type *ty, void *_) { case TYunion: kind = "union"; agg: + *(bool *)&ty->_defined = 1; if (ty->konst) { defctype(unconstify(ty), NULL); *cname = (char *)unconstify(ty)->_cname; break; } - *cname = xasprintf("__ty%s%d", ty->agg.name ? ty->agg.name : "", id++); - pri("typedef %s %s %s;\n", kind, *cname, *cname); + if (!ty->agg.fwd) { for (int i = 0; i < ty->agg.flds.n; ++i) { struct aggfield fld = ty->agg.flds.d[i]; @@ -816,18 +851,18 @@ defctype(const struct type *ty, void *_) { } break; case TYeunion: + *(bool *)&ty->_defined = 1; if (ty->konst) { defctype(unconstify(ty), NULL); *cname = (char *)unconstify(ty)->_cname; break; } + for (int i = 0; i < ty->agg.flds.n; ++i) { struct aggfield *fld = &ty->agg.flds.d[i]; if (fld->ty) defctype(fld->ty, NULL); } - *cname = xasprintf("__ty%s%d", ty->agg.name ? ty->agg.name : "", id++); - pri("typedef struct %s %s;\n", *cname, *cname); if (!ty->agg.fwd) { pri("struct %s {\n", *cname); pri("%t t;\n", ty->agg.enumty); @@ -861,6 +896,7 @@ cgen(FILE *fp, const struct comfile *cf) { outfp = fp; prelude(); + visittypes(declctype, NULL); visittypes(defctype, NULL); for (int i = 0; i < cf->decls.n; ++i) { |