aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-11 06:25:30 +0200
committerlemon <lsof@mailbox.org>2022-08-11 06:25:30 +0200
commit99cb50d4f13d587e3a0e0f2a44485f301409afb4 (patch)
treec285338782ae3cd760252337a488f10fe940e45b /bootstrap
parent8d3c3d919183a4a6ba7ad8010587dee6f5f96baa (diff)
fixs
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/all.h2
-rw-r--r--bootstrap/cgen.c46
-rw-r--r--bootstrap/env.c8
-rw-r--r--bootstrap/parse.c23
4 files changed, 50 insertions, 29 deletions
diff --git a/bootstrap/all.h b/bootstrap/all.h
index 2996f62..d1d58d9 100644
--- a/bootstrap/all.h
+++ b/bootstrap/all.h
@@ -141,6 +141,7 @@ struct parser {
int envage;
int varid;
int loopid, curloop;
+ const struct type *container;
};
enum typetype {
@@ -261,6 +262,7 @@ struct decl {
char **_cname;
bool externp;
struct span span;
+ const struct type *container;
union {
const struct type *ty;
struct fn fn;
diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c
index 4a80bfb..4e4d53f 100644
--- a/bootstrap/cgen.c
+++ b/bootstrap/cgen.c
@@ -12,7 +12,7 @@ gentype(const struct type *ty) {
pri("void");
break;
case TYbool:
- pri("bool");
+ pri("_Bool");
break;
case TYint:
pri("%sint%z_t", ty->int_signed ? "" : "u",
@@ -145,7 +145,7 @@ geniniex(struct expr *ex) {
if (ex->ty->t == TYarr)
pri("[%I] = %e, ", arg->idx, &arg->ex);
else
- pri(".%s = %e, ", arg->fld, &arg->ex);
+ pri(".%s_ = %e, ", arg->fld, &arg->ex);
}
pri("}");
@@ -159,7 +159,7 @@ geneuiniex(struct expr *ex) {
else {
assert(ex->t == Eeuini);
if (ex->euini.ini)
- pri("{ /* %s */ %I, .u.%s = %e }", ex->euini.fnam, ex->euini.tag,
+ pri("{ /* %s */ %I, .u.%s_ = %e }", ex->euini.fnam, ex->euini.tag,
ex->euini.fnam, ex->euini.ini);
else
pri("{ /* %s */ %I }", ex->euini.fnam, ex->euini.tag);
@@ -249,7 +249,7 @@ genexpr(struct expr *ex) {
pri("((%t)%n)", ty, ex);
break;
case Eget:
- pri("%e%s%s%s", ex->get.lhs, ex->get.lhs->ty->t == TYptr ? "->" : ".",
+ pri("%e%s%s%s_", ex->get.lhs, ex->get.lhs->ty->t == TYptr ? "->" : ".",
(ex->get.lhs->ty->t == TYeunion
|| (ex->get.lhs->ty->t == TYptr && ex->get.lhs->ty->child->t == TYeunion) ? "u." : ""),
ex->get.fld);
@@ -396,9 +396,9 @@ genstmt(struct stmt *stmt) {
struct euswitchcase c = stmt->euswitch.cs.d[i];
pri("case /* %s */ %d: ", c.fld->name, c.vval);
if (c.capt && c.captptr)
- pri("{ %t %s_%d__ = &__stmp->u.%s;\n", c.captty, c.capt, c.captid, c.fld->name);
+ pri("{ %t %s_%d__ = &__stmp->u.%s_;\n", c.captty, c.capt, c.captid, c.fld->name);
if (c.capt && !c.captptr)
- pri("{ %t %s_%d__ = __stmp->u.%s;\n", c.captty, c.capt, c.captid, c.fld->name);
+ pri("{ %t %s_%d__ = __stmp->u.%s_;\n", c.captty, c.capt, c.captid, c.fld->name);
genblock(c.t);
if (c.capt)
pri("}\n");
@@ -503,12 +503,22 @@ liftnestedex(struct expr *ex) {
}
static void
+lifttype(const struct type *ty) {
+ if (ty->t == TYstruct || ty->t == TYunion || ty->t == TYeunion)
+ for (int i = 0; i < ty->agg.decls.n; ++i)
+ liftdecl(ty->agg.decls.d[i]);
+}
+
+static void
liftdecl(struct decl *decl) {
static int id;
switch (decl->t) {
case Dfn:
if (decl->fn.body) {
- *decl->_cname = xasprintf("__f%s_%d", decl->fn.name, id++);
+ if (decl->container)
+ *decl->_cname = xasprintf("__m%s_%s%d", decl->container->agg.name, decl->fn.name, id++);
+ else
+ *decl->_cname = xasprintf("__f%s_%d", decl->fn.name, id++);
genfn(decl->externp, *decl->_cname, &decl->fn);
}
break;
@@ -522,6 +532,16 @@ liftdecl(struct decl *decl) {
case Dlet:
liftnestedex(decl->var.ini);
break;
+ case Dtype:
+ lifttype(decl->ty);
+ break;
+ case Dtepl:
+ for (struct teplcache *cache = decl->tepl.cache; cache; cache = cache->next) {
+ for (int i = 0; i < cache->args.n; ++i) {
+ if (cache->args.d[i].typ)
+ lifttype(cache->args.d[i].ty);
+ }
+ }
default:
break;
}
@@ -634,11 +654,7 @@ gendecl(struct decl *decl, bool toplevel) {
case Dlet:
assert(!toplevel);
break;
- case Dtype:
- if (decl->ty->t == TYstruct || decl->ty->t == TYunion)
- for (int i = 0; i < decl->ty->agg.decls.n; ++i)
- liftdecl(decl->ty->agg.decls.d[i]);
- case Ddef: case Dtepl: case Dmacro: case Dlabel:
+ case Dtype: case Ddef: case Dtepl: case Dmacro: case Dlabel:
break;
}
}
@@ -712,7 +728,7 @@ defctype(const struct type *ty, void *_) {
pri("char _;\n");
for (int i = 0; i < ty->agg.flds.n; ++i) {
struct aggfield fld = ty->agg.flds.d[i];
- pri("%t %s;\n", fld.ty, fld.name);
+ pri("%t %s_;\n", fld.ty, fld.name);
}
pri("};\n");
pri("_Static_assert(sizeof(%s) == %U, \"sizeof(%t) == %U\");\n",
@@ -720,6 +736,7 @@ defctype(const struct type *ty, void *_) {
pri("_Static_assert(__alignof__(%s) == %U, \"__alignof__(%t) == %U\");\n",
*cname, (u64)ty->align, ty, (u64)ty->align);
}
+ lifttype(ty);
break;
case TYeunion:
if (ty->konst) {
@@ -736,7 +753,7 @@ defctype(const struct type *ty, void *_) {
for (int i = 0; i < ty->agg.flds.n; ++i) {
struct aggfield *fld = &ty->agg.flds.d[i];
if (fld->ty)
- pri("%t %s;\n", fld->ty, fld->name);
+ pri("%t %s_;\n", fld->ty, fld->name);
}
pri("} u;\n};\n");
pri("_Static_assert(sizeof(%s) == %U, \"sizeof(%t) == %U\");\n",
@@ -744,6 +761,7 @@ defctype(const struct type *ty, void *_) {
pri("_Static_assert(__alignof__(%s) == %U, \"__alignof__(%t) == %U\");\n",
*cname, (u64)ty->align, ty, (u64)ty->align);
}
+ lifttype(ty);
break;
}
diff --git a/bootstrap/env.c b/bootstrap/env.c
index 2c5e80f..ec80e62 100644
--- a/bootstrap/env.c
+++ b/bootstrap/env.c
@@ -32,14 +32,12 @@ envput(struct env *env, const struct decl *decl) {
static int age;
if ((d0 = envfind(&env_noparent, INT_MAX, decl->name))) {
- if (decl == d0 || !memcmp(d0, decl, sizeof *d0))
- return d0;
// modify existing forward declarations?
- if (d0->t != decl->t)
- return NULL;
if (d0->t == Dmacro && !memcmp(&decl->macro, &d0->macro, sizeof decl->macro))
return d0;
- for (int kind = TYstruct; kind <= TYunion; ++kind) {
+ if (d0->t == Dtepl && !memcmp(&decl->tepl, &d0->tepl, sizeof decl->tepl))
+ return d0;
+ for (int kind = TYstruct; kind <= TYeunion; ++kind) {
if (d0->t == Dtype && d0->ty->t == kind
&& decl->t == Dtype && decl->ty->t == kind && d0->ty->agg.fwd) {
*(size_t *)&d0->ty->size = decl->ty->size;
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index 49f01b1..297f2a9 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -754,8 +754,8 @@ parsetype(struct parser *P) {
lexexpect(P, ']');
}
child = parsetype(P);
- if (!completetype(child))
- fatal(P, tok.span, "%s of incomplete type (%t)", slice ? "slice" : "array", child);
+ if (!slice && !completetype(child))
+ fatal(P, tok.span, "array of incomplete type (%t)", child);
if (slice)
return mkslicetype(child);
else
@@ -2641,17 +2641,17 @@ parseagg(struct parser *P, const char *name, int kind, struct decl **retdecl) {
return interntype(ty);
} else {
if (name) {
- int iid;
struct env env_noparent = *P->curenv;
env_noparent.parent = NULL;
struct decl *decl = (struct decl *)envfind(&env_noparent, P->envage, name);
- if (decl && decl->ty->t == kind)
- iid = decl->ty->agg.id;
- else
- iid = id++;
- pty = interntype((struct type) {
- kind, .agg.name = name, .agg.id = iid
- });
+ if (decl && decl->t == Dtype && decl->ty->t == kind) {
+ pty = decl->ty;
+ } else {
+ pty = interntype((struct type) {
+ kind, .agg.name = name, .agg.id = id++
+ });
+ }
+
*retdecl = decl = putdecl(P, P->tokspan, &(struct decl) {
Dtype, name, .span = P->tokspan, .ty = pty });
} else {
@@ -2753,11 +2753,13 @@ parseagg(struct parser *P, const char *name, int kind, struct decl **retdecl) {
};
pushenv(P, &env);
+ P->container = pty;
while (!lexmatch(P, &tok, '}')) {
ppty->agg.decls.d = decls.data;
ppty->agg.decls.n = decls.length;
parsedecl(aggdeclyield, &yarg, P, 0);
}
+ P->container = NULL;
vec_slice_cpy(&ppty->agg.decls, &decls);
popenv(P);
@@ -2916,6 +2918,7 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) {
struct decl decl = {0};
struct decl* decl2 = NULL;
struct attr attr = {0};
+ decl.container = P->container;
if (lexmatch(P, &tok, '#')) {
lexexpect(P, '[');