diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-14 20:19:52 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-14 20:19:52 -0500 |
commit | eceeb4aa21275a25c87bdd4907dfd8378db7c3ab (patch) | |
tree | 61d06e3f8f2184182d494398ed899020dd1e1a7f | |
parent | 1de39ba1ffdacf6841f925537b31b32a4101b632 (diff) |
declarations of imported things in C!!!
-rw-r--r-- | cgen.c | 38 | ||||
-rw-r--r-- | decls_cgen.c | 34 | ||||
-rw-r--r-- | package.c | 13 | ||||
-rw-r--r-- | toc.c | 2 |
4 files changed, 63 insertions, 24 deletions
@@ -288,7 +288,7 @@ static inline void cgen_ident_simple(CGenerator *g, Identifier i) { static void cgen_ident(CGenerator *g, Identifier i) { IdentDecl *idecl = ident_decl(i); - if (idecl && idecl->kind == IDECL_DECL && idecl->decl->flags & DECL_EXPORT) { + if (idecl && idecl->kind == IDECL_DECL && (idecl->decl->flags & DECL_EXPORT)) { assert(g->pkg_prefix); cgen_write(g, "%s__", g->pkg_prefix); } @@ -485,23 +485,10 @@ static void cgen_full_fn_name(CGenerator *g, FnExpr *f, U64 instance) { } } -/* unless f has const/semi-const args, instance and which_are_const can be set to 0 */ -static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) { +static bool cgen_fn_args(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) { + (void)instance; /* not needed atm */ bool out_param = cgen_uses_ptr(&f->ret_type); bool any_params = false; - assert(cgen_should_gen_fn(f)); - if (!f->export.id) /* local to this translation unit */ - cgen_write(g, "static "); - if (out_param) { - cgen_write(g, "void "); - } else { - if (!cgen_type_pre(g, &f->ret_type, where)) return false; - cgen_write(g, " "); - } - cgen_full_fn_name(g, f, instance); - if (!out_param) { - if (!cgen_type_post(g, &f->ret_type, where)) return false; - } cgen_write(g, "("); int semi_const_idx = 0; bool any_args = false; @@ -552,6 +539,25 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instanc return true; } +/* unless f has const/semi-const args, instance and which_are_const can be set to 0 */ +static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) { + bool out_param = cgen_uses_ptr(&f->ret_type); + assert(cgen_should_gen_fn(f)); + if (!f->export.id) /* local to this translation unit */ + cgen_write(g, "static "); + if (out_param) { + cgen_write(g, "void "); + } else { + if (!cgen_type_pre(g, &f->ret_type, where)) return false; + cgen_write(g, " "); + } + cgen_full_fn_name(g, f, instance); + if (!out_param) { + if (!cgen_type_post(g, &f->ret_type, where)) return false; + } + return cgen_fn_args(g, f, where, instance, which_are_const); +} + /* Either set_expr or set_str should be NULL and either to_expr or to_str should be NULL diff --git a/decls_cgen.c b/decls_cgen.c index 278971f..7af527d 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -112,12 +112,36 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) { IdentDecl *idecl = ident_decl(ident); assert(idecl); - if (idecl->kind == IDECL_DECL) { + if (idecl->kind == IDECL_DECL && e->type.kind == TYPE_FN) { Declaration *d = idecl->decl; - if (((d->flags & DECL_FOUND_VAL) && e->type.kind == TYPE_FN) - || (d->expr.kind == EXPR_FN)) { - /* extern function declaration */ - break; + FnExpr *f = NULL; + if (d->flags & DECL_FOUND_VAL) + f = d->val.fn; + else if (d->expr.kind == EXPR_FN) + f = d->expr.fn; + if (f) { + if (e->binary.lhs->type.flags & TYPE_IS_RESOLVED) { /* no declarations for templates */ + bool out_param = cgen_uses_ptr(&f->ret_type); + /* extern function declaration */ + cgen_write(g, "extern "); + if (out_param) { + cgen_write(g, "void"); + } else { + if (!cgen_type_pre(g, &f->ret_type, e->where)) + return false; + } + cgen_write(g, " %s__", e->binary.lhs->val.pkg->c.prefix); + cgen_ident(g, ident); + if (!out_param) { + if (!cgen_type_post(g, &f->ret_type, e->where)) + return false; + } + if (!cgen_fn_args(g, f, e->where, 0, 0)) + return false; + cgen_write(g, ";"); + cgen_nl(g); + break; + } } } /* extern variable declaration */ @@ -29,6 +29,9 @@ static inline void *imptr_malloc(Importer *i, size_t n) { return allocr_malloc(i->allocr, n); } +static inline void *imptr_calloc(Importer *i, size_t n, size_t s) { + return allocr_calloc(i->allocr, n, s); +} static inline void export_u8(Exporter *ex, U8 u8) { write_u8(ex->out, u8); @@ -331,10 +334,10 @@ static bool export_type(Exporter *ex, Type *type, Location where) { } static inline Type *imptr_new_type(Importer *im) { - return imptr_malloc(im, sizeof(Type)); + return imptr_calloc(im, 1, sizeof(Type)); } static inline Expression *imptr_new_expr(Importer *im) { - return imptr_malloc(im, sizeof(Expression)); + return imptr_calloc(im, 1, sizeof(Expression)); } static void import_type(Importer *im, Type *type) { @@ -891,7 +894,7 @@ static void import_expr(Importer *im, Expression *e) { s->to = import_optional_expr(im); } break; case EXPR_EACH: { - EachExpr *ea = e->each = imptr_malloc(im, sizeof *ea); + EachExpr *ea = e->each = imptr_calloc(im, 1, sizeof *ea); ea->flags = import_u8(im); if ((ea->flags & EACH_ANNOTATED_TYPE) || found_type) import_type(im, &ea->type); @@ -1061,6 +1064,8 @@ static bool export_fn(Exporter *ex, FnExpr *f) { export_ident_name(ex, *ident); } } + if (!export_type(ex, &f->ret_type, f->where)) + return false; export_len(ex, arr_len(f->ret_decls)); arr_foreach(f->ret_decls, Declaration, ret_decl) if (!export_decl(ex, ret_decl)) @@ -1077,6 +1082,7 @@ static void import_fn(Importer *im, FnExpr *f) { arr_foreach(f->params, Declaration, param) { import_decl(im, param); } + import_type(im, &f->ret_type); import_arr(im, &f->ret_decls); arr_foreach(f->ret_decls, Declaration, ret_decl) import_decl(im, ret_decl); @@ -1199,6 +1205,7 @@ static bool import_footer(Importer *im) { import_struct(im, s); import_arr(im, &im->fns); + arr_zero(im->fns); arr_foreach(im->fns, FnExpr, f) { import_fn(im, f); } @@ -24,8 +24,10 @@ #define this this_ #define export export_ #elif __STDC_VERSION__ < 199901 +#ifndef inline #define inline #endif +#endif #if __STDC_VERSION__ >= 201112 #define possibly_static_assert(cond) static_assert(cond, "Assertion " #cond " failed.") |