Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 28 additions & 31 deletions generator/c/c_generator.c2
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,30 @@ fn void Generator.emitStruct(Generator* gen, string_buffer.Buf* out, Decl* d, u3
}
}

fn void Generator.emitFunctionParam(Generator* gen, string_buffer.Buf* out, QualType qt, u32 name_idx, u32 arg_num) {
char[16] temp;
const char* name;
if (name_idx) {
name = gen.idx2name(name_idx);
} else {
// some compilers do not accept unnamed arguments in function definitions
snprintf(temp, elemsof(temp), "_arg%d", arg_num);
name = temp;
}
if (qt.isFunction()) {
FunctionType* ft = qt.getFunctionType();
FunctionDecl* fd = ft.getDecl();
if (fd.isParam()) {
gen.gen_member_type_func(fd, out, name);
return;
}
// TODO: when to we get here?
}
gen.emitTypePre(out, qt);
out.space();
out.add(name);
}

fn void Generator.emitFunctionType(Generator* gen, string_buffer.Buf* out, Decl* d) {
FunctionTypeDecl* ftd = (FunctionTypeDecl*)d;
FunctionDecl* fd = ftd.getDecl();
Expand All @@ -474,15 +498,9 @@ fn void Generator.emitFunctionType(Generator* gen, string_buffer.Buf* out, Decl*
u32 num_params = fd.getNumParams();
VarDecl** params = fd.getParams();
for (u32 i=0; i<num_params; i++) {
Decl* arg = (Decl*)params[i];
if (i != 0) out.add(", ");
gen.emitTypePre(out, arg.getType());
out.space();
if (arg.getNameIdx()) {
gen.emitName(out, arg);
} else {
out.print("_arg%d", i);
}
Decl* arg = (Decl*)params[i];
gen.emitFunctionParam(out, arg.getType(), arg.getNameIdx(), i);
}
if (fd.isVariadic()) {
if (num_params) out.add(", ");
Expand Down Expand Up @@ -903,30 +921,9 @@ fn void Generator.emitFuncParams(Generator* gen, FunctionDecl* fd, string_buffer

VarDecl** params = fd.getParams();
for (u32 i=0; i<num_params; i++) {
Decl* argx = (Decl*)params[i];
if (i != 0) out.add(", ");
char[8] temp;
const char* name;
u32 name_idx = argx.getNameIdx();
if (name_idx) {
name = gen.idx2name(name_idx);
} else {
snprintf(temp, elemsof(temp), "_arg%d", i);
name = temp;
}
QualType qt = argx.getType();
if (qt.isFunction()) {
FunctionType* ft = qt.getFunctionType();
FunctionDecl* fd2 = ft.getDecl();
if (fd2.isParam()) {
gen.gen_member_type_func(fd2, out, name);
continue;
}
}

gen.emitTypePre(out, qt);
out.space();
out.add(name);
Decl* arg = (Decl*)params[i];
gen.emitFunctionParam(out, arg.getType(), arg.getNameIdx(), i);
}
if (fd.isVariadic()) {
if (num_params) out.add(", ");
Expand Down
30 changes: 29 additions & 1 deletion test/functions/func_param_nested.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
// @file{file1}
module test;

fn void foo() { foo1(foo); }
fn void foo1(fn void()) { foo2(foo1); }
fn void foo2(fn void(fn void())) { foo3(foo2); }
fn void foo3(fn void(fn void(fn void()))) {}

type Cb1 fn void(void*, fn bool(i32, i32), i32);
type Cb2 fn bool(i32, i32);

Expand All @@ -30,16 +35,39 @@ fn void test2() {
test1(nil, nil, nil, 10);
}
// @expect{atleast, cgen/build.c}
typedef void (*test_Cb1)(void* _arg0, _arg1, int _arg2);
typedef void (*test_Cb1)(void* _arg0, bool (*_arg1)(int _arg0, int _arg1), int _arg2);
typedef bool (*test_Cb2)(int _arg0, int _arg1);

static void test_callback1(void* arg, bool (*_arg1)(int _arg0, int _arg1), int a);
static test_Cb1 test_cb1 = test_callback1;
static bool test_callback2(int a, int b);
static test_Cb2 test_cb2 = test_callback2;
static void test_foo(void);
static void test_foo1(void (*_arg0)(void));
static void test_foo2(void (*_arg0)(void (*_arg0)(void)));
static void test_foo3(void (*_arg0)(void (*_arg0)(void (*_arg0)(void))));
static void test_test1(void* arg, void (*cb)(void* arg, bool (*_arg1)(int _arg0, int _arg1), int a), bool (*inner)(int _arg0, int _arg1), int a);
static void test_test2(void);

static void test_foo(void)
{
test_foo1(test_foo);
}

static void test_foo1(void (*_arg0)(void))
{
test_foo2(test_foo1);
}

static void test_foo2(void (*_arg0)(void (*_arg0)(void)))
{
test_foo3(test_foo2);
}

static void test_foo3(void (*_arg0)(void (*_arg0)(void (*_arg0)(void))))
{
}

static void test_callback1(void* arg, bool (*_arg1)(int _arg0, int _arg1), int a)
{
}
Expand Down
Loading