summaryrefslogtreecommitdiff
path: root/mi
diff options
context:
space:
mode:
authorS. Gilles <sgilles@math.umd.edu>2018-03-13 10:53:55 -0400
committerS. Gilles <sgilles@math.umd.edu>2018-03-13 10:53:55 -0400
commit599feae2daa1392f20e1dc807c58bcd74c20b45e (patch)
treea358d75af648afa2aa08a465c374ef32210c48ab /mi
parent5e1154d69efc86f5fe3831b047e3531d9cfd3478 (diff)
parent2c113af58d9f63bc4f720adbb6aa8ac2cae52781 (diff)
downloadmc-599feae2daa1392f20e1dc807c58bcd74c20b45e.tar.gz
Merge branch 'autoexpr' into libmath
Diffstat (limited to 'mi')
-rw-r--r--mi/flatten.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/mi/flatten.c b/mi/flatten.c
index aba73cd..fd1c389 100644
--- a/mi/flatten.c
+++ b/mi/flatten.c
@@ -114,10 +114,10 @@ islbl(Node *n)
static Node *
temp(Flattenctx *flatten, Node *e)
{
- Node *t, *dcl;
+ Node *t;
assert(e->type == Nexpr);
- t = gentemp(e->loc, e->expr.type, &dcl);
+ t = gentemp(e->loc, e->expr.type, NULL);
return t;
}
@@ -225,23 +225,20 @@ traitfn(Srcloc loc, Trait *tr, char *fn, Type *ty)
}
static void
-dispose(Flattenctx *s, Stab *st)
+dispose(Flattenctx *s, Stab *st, size_t n)
{
- Node *d, *call, *func, *val;
+ Node *e, *call, *func;
Trait *tr;
Type *ty;
size_t i;
tr = traittab[Tcdisp];
- /* dispose in reverse order of declaration */
- for (i = st->nautodcl; i-- > 0;) {
- d = st->autodcl[i];
- ty = decltype(d);
- val = mkexpr(Zloc, Ovar, d->decl.name, NULL);
- val->expr.type = ty;
- val->expr.did = d->decl.did;
+ /* dispose in reverse order of appearance */
+ for (i = st->nautotmp; i-- > n;) {
+ e = st->autotmp[i];
+ ty = exprtype(e);
func = traitfn(Zloc, tr, "__dispose__", ty);
- call = mkexpr(Zloc, Ocall, func, val, NULL);
+ call = mkexpr(Zloc, Ocall, func, e, NULL);
call->expr.type = mktype(Zloc, Tyvoid);
flatten(s, call);
}
@@ -460,18 +457,23 @@ assign(Flattenctx *s, Node *lhs, Node *rhs)
/* returns 1 when the exit jump needs to be emitted */
static int
-exitscope(Flattenctx *s, Stab *stop, Srcloc loc, int x)
+exitscope(Flattenctx *s, Stab *stop, Srcloc loc, Exit x)
{
+ Node *exit;
Stab *st;
for (st = s->curst;; st = st->super) {
- if (st->exit[x]) {
- jmp(s, st->exit[x]);
+ exit = st->exit[x];
+ if (st->ndisposed[x] < st->nautotmp) {
+ st->exit[x] = genlbl(loc);
+ flatten(s, st->exit[x]);
+ dispose(s, st, st->ndisposed[x]);
+ st->ndisposed[x] = st->nautotmp;
+ }
+ if (exit) {
+ jmp(s, exit);
return 0;
}
- st->exit[x] = genlbl(loc);
- flatten(s, st->exit[x]);
- dispose(s, st);
if ((!stop && st->isfunc) || st == stop) {
return 1;
}
@@ -503,6 +505,12 @@ rval(Flattenctx *s, Node *n)
r = NULL;
args = n->expr.args;
switch (exprop(n)) {
+ case Oauto:
+ r = rval(s, n->expr.args[0]);
+ t = temp(s, r);
+ r = asn(t, r);
+ lappend(&s->curst->autotmp, &s->curst->nautotmp, t);
+ break;
case Osize:
r = n; /* don't touch subexprs; they're a pseudo decl */
break;
@@ -696,7 +704,10 @@ flattenblk(Flattenctx *s, Node *n)
flatten(s, n->block.stmts[i]);
}
assert(s->curst == n->block.scope);
- dispose(s, s->curst);
+ if (st->isfunc)
+ exitscope(s, NULL, Zloc, Xret);
+ else
+ dispose(s, s->curst, 0);
s->curst = st;
}