summaryrefslogtreecommitdiff
path: root/decls_cgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'decls_cgen.c')
-rw-r--r--decls_cgen.c34
1 files changed, 29 insertions, 5 deletions
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 */