aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/env.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-06 14:10:19 +0200
committerlemon <lsof@mailbox.org>2022-08-06 14:10:29 +0200
commitb8d9ad1f6636f46a832b0f949ce7525ae08f53bd (patch)
tree037c7e0a86835b2e284df786e3ba2680b7677cc4 /bootstrap/env.c
parent1dd19e56fb81d1334bb21e4aa097f9593576feb7 (diff)
basic method calls & many bugfix
Diffstat (limited to 'bootstrap/env.c')
-rw-r--r--bootstrap/env.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/bootstrap/env.c b/bootstrap/env.c
index 0c0021b..477c267 100644
--- a/bootstrap/env.c
+++ b/bootstrap/env.c
@@ -30,21 +30,37 @@ declscompatible(const struct decl *a, const struct decl *b) {
return 0;
}
-bool
+struct decl *
envput(struct env *env, const struct decl *decl) {
struct decls *decls;
struct env env_noparent = {
.decls = env->decls
};
- struct decl *decl0;
- if ((decl0 = envfind(&env_noparent, decl->name))) {
- if (!declsshadowable(decl0, decl) && !declscompatible(decl0, decl))
- return 0;
+ struct decl *d0;
+ if ((d0 = envfind(&env_noparent, decl->name))) {
+ for (int kind = TYstruct; kind <= TYunion; ++kind) {
+ if (d0->t == Dtype && d0->ty->t == kind
+ && decl->t == Dtype && decl->ty->t == kind && d0->ty->agg.fwd) {
+ // modify existing forward declaration
+ *(size_t *)&d0->ty->size = decl->ty->size;
+ *(size_t *)&d0->ty->align = decl->ty->align;
+ *(bool *)&d0->ty->agg.fwd = 0;
+ memcpy((void *)&d0->ty->agg.flds, &decl->ty->agg.flds,
+ sizeof d0->ty->agg.flds);
+ memcpy((void *)&d0->ty->agg.decls, &decl->ty->agg.decls,
+ sizeof d0->ty->agg.decls);
+ d0->span = decl->span;
+ return d0;
+ }
+ }
+ if (!declsshadowable(d0, decl) && !declscompatible(d0, decl)) {
+ return NULL;
+ }
}
decls = xcalloc(1, sizeof *decls);
decls->next = env->decls;
decls->decl = *decl;
env->decls = decls;
- return 1;
+ return &decls->decl;
}