Skip to content

Commit a70adff

Browse files
committed
Merge branch 'master' of github.com:rust-lang/rust-bindgen into objc-category-inheritance
2 parents 6a2c809 + 1565fd4 commit a70adff

29 files changed

+475
-113
lines changed

CHANGELOG.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ Released YYYY/MM/DD
120120

121121
## Added
122122

123-
* TODO (or remove section if none)
123+
* Objective-c bindings generate `From<ChildClass> for ParentClass` as well as `TryFrom<ParentClass> for ChildClass` ([#1883][]).
124124

125125
## Changed
126126

127-
* TODO (or remove section if none)
127+
* Objective-c bindings borrow self rather than take ownership ([#1883][]).
128128

129129
## Deprecated
130130

@@ -136,12 +136,15 @@ Released YYYY/MM/DD
136136

137137
## Fixed
138138

139-
* TODO (or remove section if none)
139+
* Fixed objective-c protocol impl blocks for parent classes's protocols ([#1883][]).
140140

141141
## Security
142142

143143
* TODO (or remove section if none)
144144

145+
146+
[#1883]: https://github.com/rust-lang/rust-bindgen/issues/1883
147+
145148
--------------------------------------------------------------------------------
146149

147150
# 0.55.1

bindgen-integration/build.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
extern crate bindgen;
22
extern crate cc;
33

4-
use bindgen::callbacks::{MacroParsingBehavior, ParseCallbacks, IntKind};
5-
use bindgen::Builder;
4+
use bindgen::callbacks::{IntKind, MacroParsingBehavior, ParseCallbacks};
5+
use bindgen::{Builder, EnumVariation};
66
use std::collections::HashSet;
77
use std::env;
88
use std::path::PathBuf;
@@ -147,7 +147,9 @@ fn main() {
147147
let bindings = Builder::default()
148148
.rustfmt_bindings(false)
149149
.enable_cxx_namespaces()
150-
.rustified_enum(".*")
150+
.default_enum_style(EnumVariation::Rust {
151+
non_exhaustive: false,
152+
})
151153
.raw_line("pub use self::root::*;")
152154
.raw_line("extern { fn my_prefixed_function_to_remove(i: i32); }")
153155
.module_raw_line("root::testing", "pub type Bar = i32;")
@@ -159,6 +161,8 @@ fn main() {
159161
seen_funcs: Mutex::new(0),
160162
}))
161163
.blacklist_function("my_prefixed_function_to_remove")
164+
.constified_enum("my_prefixed_enum_to_be_constified")
165+
.opaque_type("my_prefixed_templated_foo<my_prefixed_baz>")
162166
.generate()
163167
.expect("Unable to generate bindings");
164168

bindgen-integration/cpp/Test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,4 @@ Seventh::assert(bool first,
134134

135135
int my_prefixed_function_name() {
136136
return 4;
137-
}
137+
}

bindgen-integration/cpp/Test.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,21 @@ struct my_prefixed_foo {
210210
my_prefixed_bar member;
211211
};
212212

213+
enum my_prefixed_enum_to_be_constified {
214+
ONE = 1,
215+
TWO,
216+
THREE,
217+
};
218+
219+
struct my_prefixed_baz {
220+
char foo[30];
221+
};
222+
223+
template<typename T>
224+
struct my_prefixed_templated_foo {
225+
T member;
226+
};
227+
228+
my_prefixed_templated_foo<my_prefixed_baz> TEMPLATED_CONST_VALUE;
229+
213230
void my_prefixed_function_to_remove();

bindgen-integration/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,12 @@ fn test_item_rename() {
245245
};
246246
}
247247

248+
#[test]
249+
fn test_matching_with_rename() {
250+
assert_eq!(bindings::enum_to_be_constified_THREE, 3);
251+
assert_eq!(unsafe { bindings::TEMPLATED_CONST_VALUE.len() }, 30);
252+
}
253+
248254
#[test]
249255
fn test_macro_customintkind_path() {
250256
let v: &std::any::Any = &bindings::TESTMACRO_CUSTOMINTKIND_PATH;

csmith-fuzzing/predicate.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
reducing.add_argument(
8181
"--bindings-grep",
8282
type=str,
83+
nargs='*',
8384
help="Exit non-zero if the given regexp pattern is not found in the emitted bindings.")
8485

8586
reducing.add_argument(
@@ -218,11 +219,11 @@ def run_bindgen(args, bindings):
218219
if not args.expect_bindgen_fail and child.returncode != 0:
219220
exit_1("Error: running `bindgen` failed", child)
220221

221-
if args.bindings_grep:
222-
pattern = regexp(args.bindings_grep)
222+
for arg in args.bindings_grep:
223+
pattern = regexp(arg)
223224
with open(bindings, mode="r") as f:
224225
if not contains(pattern, f):
225-
print("Error: expected the emitted bindings to contain '{}', but they didn't".format(args.bindings_grep))
226+
print("Error: expected the emitted bindings to contain '{}', but they didn't".format(arg))
226227
print("---------- {} ----------------------------------------------".format(bindings))
227228
f.seek(0)
228229
print(f.read())

src/codegen/mod.rs

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ impl<'a> CodegenResult<'a> {
239239
saw_objc: false,
240240
saw_block: false,
241241
saw_bitfield_unit: false,
242-
codegen_id: codegen_id,
242+
codegen_id,
243243
items_seen: Default::default(),
244244
functions_seen: Default::default(),
245245
vars_seen: Default::default(),
@@ -987,9 +987,9 @@ impl<'a> Vtable<'a> {
987987
base_classes: &'a [Base],
988988
) -> Self {
989989
Vtable {
990-
item_id: item_id,
991-
methods: methods,
992-
base_classes: base_classes,
990+
item_id,
991+
methods,
992+
base_classes,
993993
}
994994
}
995995
}
@@ -3806,7 +3806,7 @@ fn objc_method_codegen(
38063806
}
38073807
} else {
38083808
let fn_args = fn_args.clone();
3809-
let args = iter::once(quote! { self }).chain(fn_args.into_iter());
3809+
let args = iter::once(quote! { &self }).chain(fn_args.into_iter());
38103810
quote! {
38113811
( #( #args ),* ) #fn_ret
38123812
}
@@ -3825,7 +3825,7 @@ fn objc_method_codegen(
38253825
}
38263826
} else {
38273827
quote! {
3828-
msg_send!(self, #methods_and_args)
3828+
msg_send!(*self, #methods_and_args)
38293829
}
38303830
};
38313831

@@ -3901,7 +3901,7 @@ impl CodeGenerator for ObjCInterface {
39013901
if !self.is_category() && !self.is_protocol() {
39023902
let struct_block = quote! {
39033903
#[repr(transparent)]
3904-
#[derive(Clone, Copy)]
3904+
#[derive(Clone)]
39053905
pub struct #class_name(pub id);
39063906
impl std::ops::Deref for #class_name {
39073907
type Target = objc::runtime::Object;
@@ -3921,7 +3921,9 @@ impl CodeGenerator for ObjCInterface {
39213921
}
39223922
};
39233923
result.push(struct_block);
3924+
let mut protocol_set: HashSet<ItemId> = Default::default();
39243925
for protocol_id in self.conforms_to.iter() {
3926+
protocol_set.insert(*protocol_id);
39253927
let protocol_name = ctx.rust_ident(
39263928
ctx.resolve_type(protocol_id.expect_type_id(ctx))
39273929
.name()
@@ -3942,26 +3944,73 @@ impl CodeGenerator for ObjCInterface {
39423944
.expect_type()
39433945
.kind();
39443946

3945-
parent_class = if let TypeKind::ObjCInterface(ref parent) =
3946-
parent
3947-
{
3948-
let parent_name = ctx.rust_ident(parent.rust_name());
3949-
let impl_trait = if parent.is_template() {
3950-
let template_names: Vec<Ident> = parent
3951-
.template_names
3952-
.iter()
3953-
.map(|g| ctx.rust_ident(g))
3954-
.collect();
3955-
quote! {
3956-
impl <#(#template_names :'static),*> #parent_name <#(#template_names),*> for #class_name {
3947+
let parent = match parent {
3948+
TypeKind::ObjCInterface(ref parent) => parent,
3949+
_ => break,
3950+
};
3951+
parent_class = parent.parent_class;
3952+
3953+
let parent_name = ctx.rust_ident(parent.rust_name());
3954+
let impl_trait = if parent.is_template() {
3955+
let template_names: Vec<Ident> = parent
3956+
.template_names
3957+
.iter()
3958+
.map(|g| ctx.rust_ident(g))
3959+
.collect();
3960+
quote! {
3961+
impl <#(#template_names :'static),*> #parent_name <#(#template_names),*> for #class_name {
3962+
}
3963+
}
3964+
} else {
3965+
quote! {
3966+
impl #parent_name for #class_name { }
3967+
}
3968+
};
3969+
result.push(impl_trait);
3970+
for protocol_id in parent.conforms_to.iter() {
3971+
if protocol_set.insert(*protocol_id) {
3972+
let protocol_name = ctx.rust_ident(
3973+
ctx.resolve_type(protocol_id.expect_type_id(ctx))
3974+
.name()
3975+
.unwrap(),
3976+
);
3977+
let impl_trait = quote! {
3978+
impl #protocol_name for #class_name { }
3979+
};
3980+
result.push(impl_trait);
3981+
}
3982+
}
3983+
if !parent.is_template() {
3984+
let parent_struct_name = parent.name();
3985+
let child_struct_name = self.name();
3986+
let parent_struct = ctx.rust_ident(parent_struct_name);
3987+
let from_block = quote! {
3988+
impl From<#class_name> for #parent_struct {
3989+
fn from(child: #class_name) -> #parent_struct {
3990+
#parent_struct(child.0)
39573991
}
39583992
}
3959-
} else {
3960-
quote! {
3961-
impl #parent_name for #class_name { }
3993+
};
3994+
result.push(from_block);
3995+
3996+
let error_msg = format!(
3997+
"This {} cannot be downcasted to {}",
3998+
parent_struct_name, child_struct_name
3999+
);
4000+
let try_into_block = quote! {
4001+
impl std::convert::TryFrom<#parent_struct> for #class_name {
4002+
type Error = &'static str;
4003+
fn try_from(parent: #parent_struct) -> Result<#class_name, Self::Error> {
4004+
let is_kind_of : bool = unsafe { msg_send!(parent, isKindOfClass:class!(#class_name))};
4005+
if is_kind_of {
4006+
Ok(#class_name(parent.0))
4007+
} else {
4008+
Err(#error_msg)
4009+
}
4010+
}
39624011
}
39634012
};
3964-
result.push(impl_trait);
4013+
result.push(try_into_block);
39654014
for (category_name, category_template_names) in
39664015
&parent.categories
39674016
{

src/ir/enum_ty.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use super::item::Item;
66
use super::ty::{Type, TypeKind};
77
use crate::clang;
88
use crate::ir::annotations::Annotations;
9-
use crate::ir::item::ItemCanonicalPath;
109
use crate::parse::{ClangItemParser, ParseError};
1110
use crate::regex_set::RegexSet;
1211

@@ -153,7 +152,7 @@ impl Enum {
153152
enums: &RegexSet,
154153
item: &Item,
155154
) -> bool {
156-
let path = item.canonical_path(ctx);
155+
let path = item.path_for_whitelisting(ctx);
157156
let enum_ty = item.expect_type();
158157

159158
if enums.matches(&path[1..].join("::")) {

src/ir/template.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
//! ```
2929
3030
use super::context::{BindgenContext, ItemId, TypeId};
31-
use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath};
31+
use super::item::{IsOpaque, Item, ItemAncestors};
3232
use super::traversal::{EdgeKind, Trace, Tracer};
3333
use crate::clang;
3434
use crate::parse::ClangItemParser;
@@ -306,12 +306,13 @@ impl IsOpaque for TemplateInstantiation {
306306
// correct fix is to make `canonical_{name,path}` include template
307307
// arguments properly.
308308

309-
let mut path = item.canonical_path(ctx);
309+
let mut path = item.path_for_whitelisting(ctx).clone();
310310
let args: Vec<_> = self
311311
.template_arguments()
312312
.iter()
313313
.map(|arg| {
314-
let arg_path = arg.canonical_path(ctx);
314+
let arg_path =
315+
ctx.resolve_item(*arg).path_for_whitelisting(ctx);
315316
arg_path[1..].join("::")
316317
})
317318
.collect();

0 commit comments

Comments
 (0)