Skip to content

Commit b6c4720

Browse files
committed
add support for nested functions
1 parent d1380d5 commit b6c4720

File tree

5 files changed

+32
-4
lines changed

5 files changed

+32
-4
lines changed

ctest/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ Automated tests of FFI bindings.
1414
[dependencies]
1515
syntex_syntax = "0.59.1"
1616
cc = "1.0.1"
17-
syn = { version = "0.15", features = ["full"] }
1817

1918
[workspace]
2019
members = ["testcrate"]

ctest/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
extern crate cc;
1515
extern crate syntex_syntax as syntax;
16-
extern crate syn;
1716

1817
use std::cell::RefCell;
1918
use std::collections::{HashMap, HashSet};
@@ -1208,7 +1207,7 @@ impl<'a> Generator<'a> {
12081207
let cname = cname.unwrap_or_else(|| name.to_string());
12091208

12101209
if rust_ty.contains("extern fn") {
1211-
let c_ty = c_ty.replace("(*)", &format!("(* __test_static_{}(void))", name));
1210+
let c_ty = c_ty.replacen("(*)", &format!("(* __test_static_{}(void))", name), 1);
12121211
t!(writeln!(self.c, r#"
12131212
{ty} {{
12141213
return {cname};
@@ -1318,7 +1317,13 @@ impl<'a> Generator<'a> {
13181317
if args.len() == 0 {
13191318
args.push("void".to_string());
13201319
}
1321-
format!("{}(*)({})", ret, args.join(", "))
1320+
1321+
let s = if ret.contains("(*)") {
1322+
ret.replace("(*)", &format!("(*(*)({}))", args.join(", ")))
1323+
} else {
1324+
format!("{}(*)({})", ret, args.join(", "))
1325+
};
1326+
s
13221327
}
13231328
}
13241329
ast::TyKind::Array(ref t, ref e) => {

ctest/testcrate/src/t1.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ uint8_t foo(uint8_t a, uint8_t b) { return a + b; }
2121
void bar(uint8_t a) { return; }
2222
void baz(void) { return; }
2323

24+
uint32_t (*nested(uint8_t arg))(uint16_t) {
25+
return NULL;
26+
}
27+
28+
uint32_t (*nested2(uint8_t(*arg0)(uint8_t), uint16_t(*arg1)(uint16_t)))(uint16_t) {
29+
return NULL;
30+
}
2431

2532
uint8_t (*T1_static_mut_fn_ptr)(uint8_t, uint8_t) = foo;
2633
uint8_t (*const T1_static_const_fn_ptr_unsafe)(uint8_t, uint8_t) = foo;
@@ -29,3 +36,6 @@ void (*const T1_static_const_fn_ptr_unsafe3)(void) = baz;
2936

3037
const uint8_t T1_static_right = 7;
3138
uint8_t (*T1_static_right2)(uint8_t, uint8_t) = foo;
39+
40+
uint32_t (*(*T1_fn_ptr_s)(uint8_t))(uint16_t) = nested;
41+
uint32_t (*(*T1_fn_ptr_s2)(uint8_t(*arg0)(uint8_t), uint16_t(*arg1)(uint16_t)))(uint16_t) = nested2;

ctest/testcrate/src/t1.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,13 @@ void (*const T1_static_const_fn_ptr_unsafe3)(void);
5656

5757
const uint8_t T1_static_right;
5858
uint8_t (*T1_static_right2)(uint8_t, uint8_t);
59+
60+
// T1_fn_ptr_nested: function pointer to a function, taking a uint8_t, and
61+
// returning a function pointer to a function taking a uint16_t and returning a
62+
// uint32_t
63+
uint32_t (*(*T1_fn_ptr_s)(uint8_t))(uint16_t);
64+
65+
// T1_fn_ptr_nested: function pointer to a function, taking a function pointer
66+
// uint8_t -> uint8_t, and returning a function pointer to a function taking a
67+
// uint16_t and returning a uint32_t
68+
uint32_t (*(*T1_fn_ptr_s2)(uint8_t(*)(uint8_t), uint16_t(*)(uint16_t)))(uint16_t);

ctest/testcrate/src/t1.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,8 @@ extern "C" {
8484
pub static T1_static_wrong: u8;
8585
#[link_name = "T1_static_right2"]
8686
pub static mut T1_static_wrong2: extern "C" fn(u8, u8) -> u8;
87+
88+
pub static T1_fn_ptr_s: unsafe extern "C" fn(u8) -> extern fn(u16)->u32;
89+
pub static T1_fn_ptr_s2: unsafe extern "C" fn(extern fn(u8)->u8,
90+
extern fn(u16)->u16) -> extern fn(u16)->u32;
8791
}

0 commit comments

Comments
 (0)