Skip to content

Commit 32b6d8a

Browse files
adetayloremilio
authored andcommitted
Discovery callbacks for functions and methods.
This extends the existing discovery callback mechanism to report on functions and methods. At this stage, we don't say much about them, in order to be consistent with other discovery callbacks. Subsequent PRs will add extra callbacks to provide information especially about methods (virtualness, C++ visibility, etc.) Please request changes if you think that sort of information should arrive in these callbacks. Because methods are a fundamentally C++ thing, this splits the current ParseCallbacks test to cover both a .h and a .hpp header. Part of google/autocxx#124
1 parent 0f2c9f2 commit 32b6d8a

File tree

5 files changed

+150
-10
lines changed

5 files changed

+150
-10
lines changed

Diff for: bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@ enum NamedEnum {
2525
Fish,
2626
};
2727

28-
typedef enum NamedEnum AliasOfNamedEnum;
28+
typedef enum NamedEnum AliasOfNamedEnum;
29+
30+
// Functions
31+
32+
void named_function();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Methods
2+
3+
class SomeClass {
4+
public:
5+
void named_method();
6+
};

Diff for: bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs

+102-7
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,26 @@ impl ParseCallbacks for ItemDiscovery {
1717
self.0.borrow_mut().insert(_id, _item);
1818
}
1919
}
20-
#[test]
21-
pub fn test_item_discovery_callback() {
20+
21+
fn test_item_discovery_callback(header: &str, expected: HashMap<DiscoveredItemId, DiscoveredItem>) {
2222
let discovery = ItemDiscovery::default();
2323
let info = Rc::clone(&discovery.0);
2424

25+
let mut header_path = env!("CARGO_MANIFEST_DIR").to_string();
26+
header_path.push_str(header);
27+
2528
Builder::default()
26-
.header(concat!(
27-
env!("CARGO_MANIFEST_DIR"),
28-
"/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h"
29-
))
29+
.header(header_path)
3030
.parse_callbacks(Box::new(discovery))
3131
.generate()
3232
.expect("TODO: panic message");
3333

34+
35+
compare_item_caches(&info.borrow(), &expected);
36+
}
37+
38+
#[test]
39+
fn test_item_discovery_callback_c() {
3440
let expected = ItemCache::from([
3541
(
3642
DiscoveredItemId::new(10),
@@ -87,9 +93,38 @@ pub fn test_item_discovery_callback() {
8793
final_name: "_bindgen_ty_*".to_string(),
8894
},
8995
),
96+
(
97+
DiscoveredItemId::new(41),
98+
DiscoveredItem::Function {
99+
final_name: "named_function".to_string(),
100+
},
101+
),
90102
]);
103+
test_item_discovery_callback(
104+
"/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h", expected);
105+
}
91106

92-
compare_item_caches(&info.borrow(), &expected);
107+
108+
#[test]
109+
fn test_item_discovery_callback_cpp() {
110+
let expected = ItemCache::from([
111+
(
112+
DiscoveredItemId::new(1),
113+
DiscoveredItem::Struct {
114+
original_name: Some("SomeClass".to_string()),
115+
final_name: "SomeClass".to_string(),
116+
},
117+
),
118+
(
119+
DiscoveredItemId::new(2),
120+
DiscoveredItem::Method {
121+
final_name: "named_method".to_string(),
122+
parent: DiscoveredItemId::new(1),
123+
},
124+
),
125+
]);
126+
test_item_discovery_callback(
127+
"/tests/parse_callbacks/item_discovery_callback/header_item_discovery.hpp", expected);
93128
}
94129

95130
pub fn compare_item_caches(generated: &ItemCache, expected: &ItemCache) {
@@ -142,6 +177,12 @@ fn compare_item_info(
142177
DiscoveredItem::Enum { .. } => {
143178
compare_enum_info(expected_item, generated_item)
144179
}
180+
DiscoveredItem::Function { .. } => {
181+
compare_function_info(expected_item, generated_item)
182+
}
183+
DiscoveredItem::Method { .. } => {
184+
compare_method_info(expected_item, generated_item)
185+
}
145186
}
146187
}
147188

@@ -279,3 +320,57 @@ pub fn compare_alias_info(
279320

280321
compare_item_info(expected_aliased, generated_aliased, expected, generated)
281322
}
323+
324+
pub fn compare_function_info(
325+
expected_item: &DiscoveredItem,
326+
generated_item: &DiscoveredItem,
327+
) -> bool {
328+
let DiscoveredItem::Function {
329+
final_name: expected_final_name,
330+
} = expected_item
331+
else {
332+
unreachable!()
333+
};
334+
335+
let DiscoveredItem::Function {
336+
final_name: generated_final_name,
337+
} = generated_item
338+
else {
339+
unreachable!()
340+
};
341+
342+
if !compare_names(expected_final_name, generated_final_name) {
343+
return false;
344+
}
345+
true
346+
}
347+
348+
pub fn compare_method_info(
349+
expected_item: &DiscoveredItem,
350+
generated_item: &DiscoveredItem,
351+
) -> bool {
352+
let DiscoveredItem::Method {
353+
final_name: expected_final_name,
354+
parent: expected_parent,
355+
} = expected_item
356+
else {
357+
unreachable!()
358+
};
359+
360+
let DiscoveredItem::Method {
361+
final_name: generated_final_name,
362+
parent: generated_parent,
363+
} = generated_item
364+
else {
365+
unreachable!()
366+
};
367+
368+
if expected_parent != generated_parent {
369+
return false;
370+
}
371+
372+
if !compare_names(expected_final_name, generated_final_name) {
373+
return false;
374+
}
375+
true
376+
}

Diff for: bindgen/callbacks.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,22 @@ pub enum DiscoveredItem {
224224
/// The final name of the generated binding
225225
final_name: String,
226226
},
227-
// functions, modules, etc.
227+
228+
/// A function or method.
229+
Function {
230+
/// The final name used.
231+
final_name: String,
232+
},
233+
234+
/// A method.
235+
Method {
236+
/// The final name used.
237+
final_name: String,
238+
239+
/// Type to which this method belongs.
240+
parent: DiscoveredItemId,
241+
}
242+
// modules, etc.
228243
}
229244

230245
/// Relevant information about a type to which new derive attributes will be added using

Diff for: bindgen/codegen/mod.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,7 @@ impl CodeGenerator for CompInfo {
24812481

24822482
let is_rust_union = is_union && struct_layout.is_rust_union();
24832483

2484+
let discovered_id = DiscoveredItemId::new(item.id().as_usize());
24842485
ctx.options().for_each_callback(|cb| {
24852486
let discovered_item = match self.kind() {
24862487
CompKind::Struct => DiscoveredItem::Struct {
@@ -2502,7 +2503,7 @@ impl CodeGenerator for CompInfo {
25022503
};
25032504

25042505
cb.new_item_found(
2505-
DiscoveredItemId::new(item.id().as_usize()),
2506+
discovered_id,
25062507
discovered_item,
25072508
);
25082509
});
@@ -2711,6 +2712,7 @@ impl CodeGenerator for CompInfo {
27112712
&mut method_names,
27122713
result,
27132714
self,
2715+
discovered_id,
27142716
);
27152717
}
27162718
}
@@ -2729,6 +2731,7 @@ impl CodeGenerator for CompInfo {
27292731
&mut method_names,
27302732
result,
27312733
self,
2734+
discovered_id,
27322735
);
27332736
}
27342737
}
@@ -2742,6 +2745,7 @@ impl CodeGenerator for CompInfo {
27422745
&mut method_names,
27432746
result,
27442747
self,
2748+
discovered_id,
27452749
);
27462750
}
27472751
}
@@ -2999,6 +3003,7 @@ impl Method {
29993003
method_names: &mut HashSet<String>,
30003004
result: &mut CodegenResult<'_>,
30013005
_parent: &CompInfo,
3006+
parent_id: DiscoveredItemId,
30023007
) {
30033008
assert!({
30043009
let cc = &ctx.options().codegen_config;
@@ -3019,6 +3024,7 @@ impl Method {
30193024

30203025
// First of all, output the actual function.
30213026
let function_item = ctx.resolve_item(self.signature());
3027+
let id = DiscoveredItemId::new(function_item.id().as_usize());
30223028
if !function_item.process_before_codegen(ctx, result) {
30233029
return;
30243030
}
@@ -3065,6 +3071,11 @@ impl Method {
30653071

30663072
method_names.insert(name.clone());
30673073

3074+
ctx.options().for_each_callback(|cb| cb.new_item_found(id, DiscoveredItem::Method {
3075+
parent: parent_id,
3076+
final_name: name.clone(),
3077+
}));
3078+
30683079
let mut function_name = function_item.canonical_name(ctx);
30693080
if times_seen > 0 {
30703081
write!(&mut function_name, "{times_seen}").unwrap();
@@ -4540,6 +4551,7 @@ impl CodeGenerator for Function {
45404551
) -> Self::Return {
45414552
debug!("<Function as CodeGenerator>::codegen: item = {item:?}");
45424553
debug_assert!(item.is_enabled_for_codegen(ctx));
4554+
let id = DiscoveredItemId::new(item.id().as_usize());
45434555

45444556
let is_internal = matches!(self.linkage(), Linkage::Internal);
45454557

@@ -4656,6 +4668,14 @@ impl CodeGenerator for Function {
46564668
if times_seen > 0 {
46574669
write!(&mut canonical_name, "{times_seen}").unwrap();
46584670
}
4671+
ctx.options().for_each_callback(|cb| {
4672+
cb.new_item_found(
4673+
id,
4674+
DiscoveredItem::Function {
4675+
final_name: canonical_name.to_string(),
4676+
}
4677+
);
4678+
});
46594679

46604680
let link_name_attr = self.link_name().or_else(|| {
46614681
let mangled_name = mangled_name.unwrap_or(name);

0 commit comments

Comments
 (0)