Skip to content
Draft
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
104 changes: 104 additions & 0 deletions bindgen-tests/tests/expectations/tests/function-typedef-method.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions bindgen-tests/tests/headers/function-typedef-method.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// bindgen-flags: -- -std=c++17

typedef int Function(int);
using FunctionAlias = Function;

struct First {
Function method;
static Function static_method;
int value;
};

struct Second {
FunctionAlias method;
int value;
};

struct Virtual {
virtual Function method;
};

Function free_function;
22 changes: 22 additions & 0 deletions bindgen-tests/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,28 @@ fn commandline_multiple_headers() {
build_flags_output_helper(&bindings);
}

#[test]
fn test_wrap_static_function_typedef() {
let directory = tempfile::tempdir().unwrap();
let header = directory.path().join("function-typedef.h");
fs::write(
&header,
"typedef int Function(int);\nstatic Function take;\nstatic int take(int value) { return value + 10; }\n",
)
.unwrap();
let wrapper = directory.path().join("wrapper.c");
Builder::default()
.header(header.to_str().unwrap())
.wrap_static_fns(true)
.wrap_static_fns_path(&wrapper)
.generate()
.expect(
"Function typedefs must be resolved before serializing a wrapper",
);
let wrapper = fs::read_to_string(wrapper).unwrap();
assert!(wrapper.contains("return take("));
}

#[test]
fn test_wrap_static_fns() {
// This test is for testing diffs of the generated C source and header files
Expand Down
8 changes: 7 additions & 1 deletion bindgen/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,13 @@ impl ClangSubItemParser for Function {
}

// Grab the signature using Item::from_ty.
let sig = Item::from_ty(&cursor.cur_type(), cursor, None, context)?;
let mut ty = cursor.cur_type();
// Parse the signature at the function cursor so that methods declared
// through a function typedef still get their implicit receiver.
if matches!(ty.kind(), CXType_Typedef | CXType_Elaborated) {
ty = ty.canonical_type();
}
let sig = Item::from_ty(&ty, cursor, None, context)?;

let mut name = cursor.spelling();
assert!(!name.is_empty(), "Empty function name?");
Expand Down
Loading