summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c38
-rw-r--r--decls_cgen.c34
-rw-r--r--package.c13
-rw-r--r--toc.c2
4 files changed, 63 insertions, 24 deletions
diff --git a/cgen.c b/cgen.c
index 03f828d..bbb0da9 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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 */
diff --git a/package.c b/package.c
index 2c645f4..e9d6946 100644
--- a/package.c
+++ b/package.c
@@ -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);
}
diff --git a/toc.c b/toc.c
index dfa2877..d62c111 100644
--- a/toc.c
+++ b/toc.c
@@ -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.")