Skip to content

Commit b1d30d2

Browse files
committed
Deglobalize FUNC_UNSAFE & switch to function matcher
1 parent 8646617 commit b1d30d2

File tree

8 files changed

+127
-190
lines changed

8 files changed

+127
-190
lines changed

binding-generator/src/bin/settings-cleanup.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,22 @@ use std::{env, fmt};
66

77
use clang::{Entity, EntityKind};
88
use opencv_binding_generator::{
9-
opencv_module_from_path, settings, Class, EntityExt, EntityWalkerExt, EntityWalkerVisitor, Func, FuncId, Generator,
10-
GeneratorEnv,
9+
opencv_module_from_path, settings, Class, EntityExt, EntityWalkerExt, EntityWalkerVisitor, Func, Generator, GeneratorEnv,
1110
};
1211

1312
struct FunctionFinder<'tu, 'f> {
1413
pub module: &'tu str,
1514
pub gen_env: GeneratorEnv<'tu>,
1615
pub func_exclude_unused: RefCell<&'f mut HashSet<&'static str>>,
1716
pub func_cfg_attr_unused: RefCell<&'f mut HashSet<&'static str>>,
18-
pub func_unsafe_unused: RefCell<&'f mut HashSet<FuncId<'static>>>,
1917
}
2018

2119
impl<'tu, 'f> FunctionFinder<'tu, 'f> {
2220
pub fn update_used_func(&self, f: &Func) {
2321
let identifier = f.identifier();
24-
let func_id = f.func_id().make_static();
2522

2623
self.func_exclude_unused.borrow_mut().remove(identifier.as_str());
2724
self.func_cfg_attr_unused.borrow_mut().remove(identifier.as_str());
28-
self.func_unsafe_unused.borrow_mut().remove(&func_id);
2925
}
3026
}
3127

@@ -82,7 +78,6 @@ fn main() {
8278
let opencv_header_dirs = args.map(PathBuf::from);
8379
let mut func_exclude_unused = settings::FUNC_EXCLUDE.clone();
8480
let mut func_cfg_attr_unused = settings::FUNC_CFG_ATTR.keys().copied().collect::<HashSet<_>>();
85-
let mut func_unsafe_unused = settings::FUNC_UNSAFE.clone();
8681
for opencv_header_dir in opencv_header_dirs {
8782
println!("Processing header dir: {}", opencv_header_dir.display());
8883
let modules = opencv_header_dir
@@ -105,7 +100,6 @@ fn main() {
105100
gen_env,
106101
func_exclude_unused: RefCell::new(&mut func_exclude_unused),
107102
func_cfg_attr_unused: RefCell::new(&mut func_cfg_attr_unused),
108-
func_unsafe_unused: RefCell::new(&mut func_unsafe_unused),
109103
});
110104
});
111105
}
@@ -114,6 +108,4 @@ fn main() {
114108
show(func_exclude_unused);
115109
println!("Unused entries in settings::FUNC_CFG_ATTR ({}):", func_cfg_attr_unused.len());
116110
show(func_cfg_attr_unused);
117-
println!("Unused entries in settings::FUNC_UNSAFE ({}):", func_unsafe_unused.len());
118-
show(func_unsafe_unused);
119111
}

binding-generator/src/class.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -419,31 +419,35 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
419419
let def_loc = fld.file_line_name().location;
420420
let rust_module = Rc::from(fld.rust_module());
421421
let mut fld_type_ref = fld.type_ref();
422-
let fld_type_kind = fld_type_ref.kind();
423-
if fld_type_kind
424-
.as_pointer()
425-
.map_or(false, |inner| inner.kind().as_primitive().is_some())
426-
&& !fld_type_kind.is_char_ptr_string(fld_type_ref.type_hint())
427-
{
428-
fld_type_ref.to_mut().set_type_hint(TypeRefTypeHint::PrimitivePtrAsRaw);
429-
} else if fld_type_kind.as_class().map_or(false, |cls| cls.kind().is_trait()) {
430-
fld_type_ref.to_mut().set_type_hint(TypeRefTypeHint::TraitClassConcrete);
422+
let fld_refname = fld.cpp_name(CppNameStyle::Reference);
423+
if let Some(type_hint) = gen_env.settings.property_override.get(fld_refname.as_ref()) {
424+
fld_type_ref.to_mut().set_type_hint(type_hint.clone());
425+
} else {
426+
let fld_type_kind = fld_type_ref.kind();
427+
if fld_type_kind
428+
.as_pointer()
429+
.map_or(false, |inner| inner.kind().as_primitive().is_some())
430+
&& !fld_type_kind.is_char_ptr_string(fld_type_ref.type_hint())
431+
{
432+
fld_type_ref.to_mut().set_type_hint(TypeRefTypeHint::PrimitivePtrAsRaw);
433+
} else if fld_type_kind.as_class().map_or(false, |cls| cls.kind().is_trait()) {
434+
fld_type_ref.to_mut().set_type_hint(TypeRefTypeHint::TraitClassConcrete);
435+
}
431436
}
432437
let fld_type_kind = fld_type_ref.kind();
433438
let return_kind = ReturnKind::infallible(fld_type_kind.return_as_naked(fld_type_ref.type_hint()));
434439
let fld_const = fld.constness();
435440
let passed_by_ref = fld_type_kind.can_return_as_direct_reference();
436-
let fld_refname = fld.cpp_name(CppNameStyle::Reference);
437441
let rust_custom_leafname = gen_env.settings.property_rename.get(fld_refname.as_ref()).copied();
438-
let fld_declname = fld.cpp_name(CppNameStyle::Declaration);
442+
let fld_declname = fld_refname.localname();
439443
let (mut read_const_yield, mut read_mut_yield) = if fld_const.is_mut() && passed_by_ref {
440444
let read_const_func = if constness_filter.map_or(true, |c| c.is_const()) {
441445
Some(Func::new_desc(
442446
FuncDesc::new(
443447
FuncKind::FieldAccessor(self.clone(), fld.clone()),
444448
Constness::Const,
445449
return_kind,
446-
fld_declname.clone(),
450+
fld_declname,
447451
Rc::clone(&rust_module),
448452
[],
449453
fld_type_ref.as_ref().clone().with_inherent_constness(Constness::Const),
@@ -483,7 +487,7 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
483487
FuncKind::FieldAccessor(self.clone(), fld.clone()),
484488
fld_const,
485489
return_kind,
486-
fld_declname.clone(),
490+
fld_declname,
487491
Rc::clone(&rust_module),
488492
[],
489493
fld_type_ref.as_ref().clone(),

binding-generator/src/func.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::rc::Rc;
66

77
use clang::{Availability, Entity, EntityKind, ExceptionSpecification};
88
pub use desc::{FuncCppBody, FuncDesc, FuncRustBody, FuncRustExtern};
9-
pub use func_matcher::{FuncId, FuncMatchProperties, FuncMatcher, Pred};
9+
pub use func_matcher::{FuncMatchProperties, FuncMatcher, Pred};
1010
pub use kind::{FuncKind, OperatorKind, ReturnKind};
1111
use once_cell::sync::Lazy;
1212
use regex::bytes::Regex;
@@ -405,10 +405,9 @@ impl<'tu, 'ge> Func<'tu, 'ge> {
405405
}
406406

407407
pub fn safety(&self) -> Safety {
408-
// todo move FUNC_UNSAFE to gen_env.settings, but can't do that now because setAllocator is a Desc function and it needs to be unsafe
409408
let out = match self {
410-
Func::Clang { .. } => Safety::from_is_unsafe(settings::FUNC_UNSAFE.contains(&self.func_id())),
411-
Func::Desc(_) => Safety::from_is_unsafe(settings::FUNC_UNSAFE.contains(&self.func_id())),
409+
Func::Clang { gen_env, .. } => Safety::from_is_unsafe(gen_env.settings.func_unsafe.get(&mut self.matcher()).is_some()),
410+
Func::Desc(_) => Safety::Safe,
412411
};
413412
out.or_is_unsafe(|| {
414413
self.arguments().iter().any(|a| {
@@ -604,13 +603,6 @@ impl<'tu, 'ge> Func<'tu, 'ge> {
604603
out
605604
}
606605

607-
pub fn func_id(&self) -> FuncId {
608-
match self {
609-
&Self::Clang { entity, .. } => FuncId::from_entity(entity),
610-
Self::Desc(desc) => FuncId::from_desc(desc),
611-
}
612-
}
613-
614606
pub fn matcher(&self) -> FuncMatchProperties {
615607
FuncMatchProperties::new(self, self.cpp_name(CppNameStyle::Reference))
616608
}
@@ -771,7 +763,6 @@ impl fmt::Debug for Func<'_, '_> {
771763
});
772764
self
773765
.update_debug_struct(&mut debug_struct)
774-
.field("func_id", &self.func_id())
775766
.field("constness", &self.constness())
776767
.field("is_specialized", &self.is_specialized())
777768
.field("return_kind", &self.return_kind())

binding-generator/src/func/func_matcher.rs

Lines changed: 1 addition & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,11 @@
11
use std::borrow::Cow;
22
use std::borrow::Cow::Owned;
33
use std::collections::{HashMap, HashSet};
4-
use std::fmt;
5-
use std::ops::ControlFlow;
64
use std::sync::RwLock;
75

8-
use clang::{Entity, EntityKind};
9-
10-
use crate::element::UNNAMED;
11-
use crate::func::FuncDesc;
126
use crate::field::Field;
137
use crate::type_ref::Constness;
14-
use crate::{CowMapBorrowedExt, CppNameStyle, Element, EntityExt, Func, IteratorExt};
15-
16-
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
17-
pub struct FuncId<'f> {
18-
name: Cow<'f, str>,
19-
constness: Constness,
20-
args: Vec<Cow<'f, str>>,
21-
}
22-
23-
impl<'f> FuncId<'f> {
24-
/// # Parameters
25-
/// name: fully qualified C++ function name (e.g. cv::Mat::create)
26-
/// args: C++ argument names ("unnamed" for unnamed ones)
27-
pub fn new_mut<const ARGS: usize>(name: &'static str, args: [&'static str; ARGS]) -> FuncId<'static> {
28-
FuncId {
29-
name: name.into(),
30-
constness: Constness::Mut,
31-
args: args.into_iter().map(|a| a.into()).collect(),
32-
}
33-
}
34-
35-
/// # Parameters
36-
/// name: fully qualified C++ function name (e.g. cv::Mat::create)
37-
/// args: C++ argument names ("unnamed" for unnamed ones)
38-
pub fn new_const<const ARGS: usize>(name: &'static str, args: [&'static str; ARGS]) -> FuncId<'static> {
39-
FuncId {
40-
name: name.into(),
41-
constness: Constness::Const,
42-
args: args.into_iter().map(|a| a.into()).collect(),
43-
}
44-
}
45-
46-
pub fn from_entity(entity: Entity) -> FuncId<'static> {
47-
let args = if let EntityKind::FunctionTemplate = entity.get_kind() {
48-
let mut args = Vec::with_capacity(8);
49-
entity.walk_children_while(|child| {
50-
if child.get_kind() == EntityKind::ParmDecl {
51-
args.push(child.get_name().map_or(UNNAMED.into(), Cow::Owned));
52-
}
53-
ControlFlow::Continue(())
54-
});
55-
args
56-
} else {
57-
entity
58-
.get_arguments()
59-
.into_iter()
60-
.flatten()
61-
.map(|a| a.get_name().map_or(UNNAMED.into(), Cow::Owned))
62-
.collect()
63-
};
64-
FuncId {
65-
name: entity.cpp_name(CppNameStyle::Reference).into_owned().into(),
66-
constness: Constness::from_is_const(entity.is_const_method()),
67-
args,
68-
}
69-
}
70-
71-
pub fn from_desc(desc: &'f FuncDesc) -> FuncId<'f> {
72-
let mut name = desc.kind.as_instance_method().map_or_else(
73-
|| "".to_string(),
74-
|cls| format!("{}::", cls.cpp_name(CppNameStyle::Reference)),
75-
);
76-
name.push_str(desc.cpp_name.as_ref());
77-
let args = desc
78-
.arguments
79-
.iter()
80-
.map(|arg| arg.cpp_name(CppNameStyle::Declaration))
81-
.collect();
82-
83-
FuncId {
84-
name: name.into(),
85-
constness: desc.constness,
86-
args,
87-
}
88-
}
89-
90-
pub fn make_static(self) -> FuncId<'static> {
91-
FuncId {
92-
name: self.name.into_owned().into(),
93-
args: self.args.into_iter().map(|arg| arg.into_owned().into()).collect(),
94-
constness: self.constness,
95-
}
96-
}
97-
98-
pub fn name(&self) -> &str {
99-
self.name.as_ref()
100-
}
101-
102-
pub fn args(&self) -> &[Cow<str>] {
103-
&self.args
104-
}
105-
}
106-
107-
impl fmt::Display for FuncId<'_> {
108-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109-
write!(
110-
f,
111-
"FuncId::new{cnst}(\"{name}\", [{args}])",
112-
cnst = self.constness.rust_function_name_qual(),
113-
name = self.name,
114-
args = self.args.iter().map(|a| format!("\"{a}\"")).join(", ")
115-
)
116-
}
117-
}
8+
use crate::{CowMapBorrowedExt, CppNameStyle, Element, Func};
1189

11910
#[derive(Debug)]
12011
pub struct FuncMatchProperties<'f> {

binding-generator/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use entity::dbg_clang_entity;
2828
pub use entity::EntityExt;
2929
pub use enumeration::Enum;
3030
use field::Field;
31-
pub use func::{Func, FuncId, FuncTypeHint, Pred, UsageTracker};
31+
pub use func::{Func, FuncTypeHint, Pred, UsageTracker};
3232
pub use generator::{GeneratedType, Generator, GeneratorVisitor, OpenCvWalker};
3333
pub use generator_env::{ClassKindOverride, ExportConfig, GeneratorEnv};
3434
pub use iterator_ext::IteratorExt;

binding-generator/src/settings.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ macro_rules! pred {
4242
use std::collections::{BTreeSet, HashMap, HashSet};
4343

4444
pub use argument_names::{ARGUMENT_NAMES_MULTIPLE_SLICE, ARGUMENT_NAMES_NOT_SLICE, ARGUMENT_NAMES_USERDATA};
45-
pub use argument_override::{arg_override_factory, return_override_factory, ArgOverride, ReturnOverride, ARG_OVERRIDE_SELF};
45+
pub use argument_override::{
46+
arg_override_factory, property_override_factory, return_override_factory, ArgOverride, PropertyOverride, ReturnOverride,
47+
ARG_OVERRIDE_SELF,
48+
};
4649
pub use element_exclude_kind::ELEMENT_EXCLUDE_KIND;
4750
pub use element_export_tweak::ELEMENT_EXPORT_TWEAK;
4851
pub use force_infallible::{force_infallible_factory, ForceInfallible};
@@ -52,7 +55,7 @@ pub use func_inject::{func_inject_factory, FuncFactory, FuncInject};
5255
pub use func_rename::{func_rename_factory, FuncRename};
5356
pub use func_replace::{func_replace_factory, FuncInheritFactory, FuncReplace};
5457
pub use func_specialize::{func_specialize_factory, FuncSpec, FuncSpecialize};
55-
pub use func_unsafe::FUNC_UNSAFE;
58+
pub use func_unsafe::{func_unsafe_factory, FuncUnsafe};
5659
pub use generator_module_tweaks::{generator_module_tweaks_factory, ModuleTweak};
5760
pub use implemented::{
5861
IMPLEMENTED_CONST_GENERICS, IMPLEMENTED_FUNCTION_LIKE_MACROS, IMPLEMENTED_GENERICS, IMPLEMENTED_MANUAL_DEBUG,
@@ -92,7 +95,9 @@ pub struct Settings {
9295
pub func_rename: FuncRename,
9396
pub func_replace: FuncReplace,
9497
pub func_specialize: FuncSpecialize,
98+
pub func_unsafe: FuncUnsafe,
9599
pub generator_module_tweaks: ModuleTweak,
100+
pub property_override: PropertyOverride,
96101
pub property_rename: PropertyRename,
97102
}
98103

@@ -106,7 +111,9 @@ impl Settings {
106111
func_rename: FuncRename::default(),
107112
func_replace: FuncReplace::empty(),
108113
func_specialize: FuncMatcher::empty(),
114+
func_unsafe: FuncUnsafe::empty(),
109115
generator_module_tweaks: ModuleTweak::empty(),
116+
property_override: PropertyOverride::default(),
110117
property_rename: PropertyRename::default(),
111118
}
112119
}
@@ -120,7 +127,9 @@ impl Settings {
120127
func_rename: func_rename_factory(module),
121128
func_replace: func_replace_factory(module),
122129
func_specialize: func_specialize_factory(module),
130+
func_unsafe: func_unsafe_factory(module),
123131
generator_module_tweaks: generator_module_tweaks_factory(module),
132+
property_override: property_override_factory(module),
124133
property_rename: property_rename_factory(module),
125134
}
126135
}

binding-generator/src/settings/argument_override.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub const ARG_OVERRIDE_SELF: &str = "this";
99

1010
pub type ArgOverride = FuncMatcher<'static, HashMap<&'static str, TypeRefTypeHint>>;
1111
pub type ReturnOverride = FuncMatcher<'static, TypeRefTypeHint>;
12+
pub type PropertyOverride = HashMap<&'static str, TypeRefTypeHint>;
1213

1314
pub fn arg_override_factory(module: &str) -> ArgOverride {
1415
match module {
@@ -32,6 +33,13 @@ pub fn return_override_factory(module: &str) -> ReturnOverride {
3233
}
3334
}
3435

36+
pub fn property_override_factory(module: &str) -> PropertyOverride {
37+
match module {
38+
"core" => core_property_override_factory(),
39+
_ => PropertyOverride::default(),
40+
}
41+
}
42+
3543
fn calib3d_arg_override_factory() -> ArgOverride {
3644
FuncMatcher::create(HashMap::from([
3745
(
@@ -694,3 +702,10 @@ fn objdetect_return_override_factory() -> ReturnOverride {
694702
),
695703
]))
696704
}
705+
706+
fn core_property_override_factory() -> PropertyOverride {
707+
HashMap::from([(
708+
"cv::cuda::GpuMat::allocator",
709+
TypeRefTypeHint::ExplicitLifetime(Lifetime::statik()),
710+
)])
711+
}

0 commit comments

Comments
 (0)