diff options
| author | 2022-08-20 06:31:06 +0200 | |
|---|---|---|
| committer | 2022-08-20 06:31:06 +0200 | |
| commit | 19acdd751963e88b6e75693f947b1b1fd2912f11 (patch) | |
| tree | e276d518a6eee672d3b2f32381fb41b544a9d6c7 /bootstrap/cgen.c | |
| parent | 58d8abf355c1543ec6afd99189848634f51f6273 (diff) | |
defer
Diffstat (limited to 'bootstrap/cgen.c')
| -rw-r--r-- | bootstrap/cgen.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c index e047f08..94ae420 100644 --- a/bootstrap/cgen.c +++ b/bootstrap/cgen.c @@ -318,7 +318,7 @@ static void genfn(bool externp, const char *cname, struct fn *fn); static void genstatic(bool externp, const char *cname, struct var *var); static void -genstmt(struct stmt *stmt) { +genstmt(struct blockstmt *block, struct stmt *stmt) { const char *p = fileid2path(stmt->span.fileid); if (stmt->t != Sblock) pri("#line %d %S\n", stmt->span.line, p, (u64)strlen(p)); @@ -367,7 +367,7 @@ genstmt(struct stmt *stmt) { genblock(stmt->ifelse.t); if (stmt->ifelse.f) { pri("else\n"); - genstmt(stmt->ifelse.f); + genstmt(block, stmt->ifelse.f); } break; case Swhile: @@ -384,7 +384,7 @@ genstmt(struct stmt *stmt) { case Sfor: pri("{\n"); for (int i = 0; i < stmt->loop.ini.n; ++i) - genstmt(&stmt->loop.ini.d[i]); + genstmt(block, &stmt->loop.ini.d[i]); pri("for (; "); pri("%e;", &stmt->loop.test); if (stmt->loop.next) @@ -446,10 +446,22 @@ genstmt(struct stmt *stmt) { pri("}\n"); pri("}\n"); break; case Sreturn: - pri("return"); - if (stmt->retex) - pri(" %e", stmt->retex); - pri(";\n"); + pri("do { "); + if (stmt->ret.ex) { + if (stmt->ret.ex->ty->t != TYvoid) + pri("__auto_type __ret = "); + pri("%e;", stmt->ret.ex); + } + for (struct defer* defer = block->defers; defer; defer = defer->next) { + if (defer->age < stmt->ret.deferage) { + const char *p = fileid2path(defer->ex.span.fileid); + pri("\n#line %d %S\n", defer->ex.span.line, p, (u64)strlen(p)); + genexpr(&defer->ex); + pri(";\n"); + } + } + pri("return%s;", (stmt->ret.ex && stmt->ret.ex->ty->t != TYvoid) ? " __ret" : ""); + pri("} while (0);\n"); break; case Sbreak: pri("goto _brk%d;\n", stmt->brkcon.id); @@ -475,7 +487,7 @@ static void genblock(struct blockstmt block) { pri("{\n"); for (int i = 0; i < block.stmts.n; ++i) - genstmt(&block.stmts.d[i]); + genstmt(&block, &block.stmts.d[i]); pri("}\n"); } @@ -644,8 +656,8 @@ liftnested(struct stmt *stmt) { liftnested(blocktostmt(*stmt->iswitch.f)); break; case Sreturn: - if (stmt->retex) - liftnestedex(stmt->retex); + if (stmt->ret.ex) + liftnestedex(stmt->ret.ex); break; case Seuswitch: liftnestedex(&stmt->euswitch.test); @@ -687,7 +699,15 @@ genfn(bool externp, const char *cname, struct fn *fn) { if (!fn->body) { pri(";\n"); } else { + pri("{"); genblock(fn->body->block); + for (struct defer* defer = fn->body->block.defers; defer; defer = defer->next) { + const char *p = fileid2path(defer->ex.span.fileid); + pri("\n#line %d %S\n", defer->ex.span.line, p, (u64)strlen(p)); + genexpr(&defer->ex); + pri(";\n"); + } + pri("}"); } } |