diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/clang.rs | 6 | ||||
-rw-r--r-- | src/ir/context.rs | 37 | ||||
-rw-r--r-- | src/ir/item.rs | 28 | ||||
-rw-r--r-- | src/lib.rs | 14 | ||||
-rw-r--r-- | src/options.rs | 14 |
5 files changed, 89 insertions, 10 deletions
diff --git a/src/clang.rs b/src/clang.rs index 36ccd266..074d459b 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -1401,6 +1401,12 @@ impl fmt::Display for SourceLocation { } } +impl fmt::Debug for SourceLocation { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self) + } +} + /// A comment in the source text. /// /// Comments are sort of parsed by Clang, and have a tree structure. diff --git a/src/ir/context.rs b/src/ir/context.rs index ffb49d74..a9e19fb2 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1423,7 +1423,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" fn build_root_module(id: ItemId) -> Item { let module = Module::new(Some("root".into()), ModuleKind::Normal); - Item::new(id, None, None, id, ItemKind::Module(module)) + Item::new(id, None, None, id, ItemKind::Module(module), None) } /// Get the root module. @@ -1733,6 +1733,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Type(sub_ty), + Some(child.location()), ); // Bypass all the validations in add_item explicitly. @@ -1797,6 +1798,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Type(ty), + Some(location.location()), ); // Bypass all the validations in add_item explicitly. @@ -1930,6 +1932,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" ) -> TypeId { let spelling = ty.spelling(); let layout = ty.fallible_layout(self).ok(); + let location = ty.declaration().location(); let type_kind = TypeKind::ResolvedTypeRef(wrapped_id); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let item = Item::new( @@ -1938,6 +1941,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, parent_id.unwrap_or_else(|| self.current_module.into()), ItemKind::Type(ty), + Some(location), ); self.add_builtin_item(item); with_id.as_type_id_unchecked() @@ -1998,6 +2002,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let spelling = ty.spelling(); let is_const = ty.is_const(); let layout = ty.fallible_layout(self).ok(); + let location = ty.declaration().location(); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let id = self.next_item_id(); let item = Item::new( @@ -2006,6 +2011,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.root_module.into(), ItemKind::Type(ty), + Some(location), ); self.add_builtin_item(item); Some(id.as_type_id_unchecked()) @@ -2194,6 +2200,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Module(module), + Some(cursor.location()), ); let module_id = module.id().as_module_id_unchecked(); @@ -2241,11 +2248,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" assert!(self.in_codegen_phase()); assert!(self.current_module == self.root_module); - let cb = match self.options.parse_callbacks { - Some(ref cb) => cb, - None => return CanDerive::No, - }; - *self .blocklisted_types_implement_traits .borrow_mut() @@ -2255,8 +2257,27 @@ If you encounter an error missing from this list, please file an issue or a PR!" .or_insert_with(|| { item.expect_type() .name() - .and_then(|name| { - cb.blocklisted_type_implements_trait(name, derive_trait) + .and_then(|name| match self.options.parse_callbacks { + Some(ref cb) => cb.blocklisted_type_implements_trait( + name, + derive_trait, + ), + // Sized integer types from <stdint.h> get mapped to Rust primitive + // types regardless of whether they are blocklisted, so ensure that + // standard traits are considered derivable for them too. + None => match name { + "int8_t" | "uint8_t" | "int16_t" | "uint16_t" | + "int32_t" | "uint32_t" | "int64_t" | + "uint64_t" | "uintptr_t" | "intptr_t" | + "ptrdiff_t" => Some(CanDerive::Yes), + "size_t" if self.options.size_t_is_usize => { + Some(CanDerive::Yes) + } + "ssize_t" if self.options.size_t_is_usize => { + Some(CanDerive::Yes) + } + _ => Some(CanDerive::No), + }, }) .unwrap_or(CanDerive::No) }) diff --git a/src/ir/item.rs b/src/ir/item.rs index 730271ef..8692575f 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -417,6 +417,8 @@ pub struct Item { parent_id: ItemId, /// The item kind. kind: ItemKind, + /// The source location of the item. + location: Option<clang::SourceLocation>, } impl AsRef<ItemId> for Item { @@ -433,6 +435,7 @@ impl Item { annotations: Option<Annotations>, parent_id: ItemId, kind: ItemKind, + location: Option<clang::SourceLocation>, ) -> Self { debug_assert!(id != parent_id || kind.is_module()); Item { @@ -445,6 +448,7 @@ impl Item { comment, annotations: annotations.unwrap_or_default(), kind, + location, } } @@ -454,10 +458,15 @@ impl Item { ty: &clang::Type, ctx: &mut BindgenContext, ) -> TypeId { + let location = ty.declaration().location(); let ty = Opaque::from_clang_ty(ty, ctx); let kind = ItemKind::Type(ty); let parent = ctx.root_module().into(); - ctx.add_item(Item::new(with_id, None, None, parent, kind), None, None); + ctx.add_item( + Item::new(with_id, None, None, parent, kind, Some(location)), + None, + None, + ); with_id.as_type_id_unchecked() } @@ -632,6 +641,17 @@ impl Item { return true; } + if !ctx.options().blocklisted_files.is_empty() { + if let Some(location) = &self.location { + let (file, _, _, _) = location.location(); + if let Some(filename) = file.name() { + if ctx.options().blocklisted_files.matches(&filename) { + return true; + } + } + } + } + let path = self.path_for_allowlisting(ctx); let name = path[1..].join("::"); ctx.options().blocklisted_items.matches(&name) || @@ -1297,7 +1317,7 @@ impl ClangItemParser for Item { let id = ctx.next_item_id(); let module = ctx.root_module().into(); ctx.add_item( - Item::new(id, None, None, module, ItemKind::Type(ty)), + Item::new(id, None, None, module, ItemKind::Type(ty), None), None, None, ); @@ -1335,6 +1355,7 @@ impl ClangItemParser for Item { annotations, relevant_parent_id, ItemKind::$what(item), + Some(cursor.location()), ), declaration, Some(cursor), @@ -1516,6 +1537,7 @@ impl ClangItemParser for Item { None, parent_id.unwrap_or_else(|| current_module.into()), ItemKind::Type(Type::new(None, None, kind, is_const)), + Some(location.location()), ), None, None, @@ -1647,6 +1669,7 @@ impl ClangItemParser for Item { annotations, relevant_parent_id, ItemKind::Type(item), + Some(location.location()), ), declaration, Some(location), @@ -1875,6 +1898,7 @@ impl ClangItemParser for Item { None, parent, ItemKind::Type(Type::named(name)), + Some(location.location()), ); ctx.add_type_param(item, definition); Some(id.as_type_id_unchecked()) @@ -308,6 +308,7 @@ impl Builder { (&self.options.blocklisted_types, "--blocklist-type"), (&self.options.blocklisted_functions, "--blocklist-function"), (&self.options.blocklisted_items, "--blocklist-item"), + (&self.options.blocklisted_files, "--blocklist-file"), (&self.options.opaque_types, "--opaque-type"), (&self.options.allowlisted_functions, "--allowlist-function"), (&self.options.allowlisted_types, "--allowlist-type"), @@ -821,6 +822,13 @@ impl Builder { self } + /// Hide any contents of the given file from the generated bindings, + /// regardless of whether it's a type, function, module etc. + pub fn blocklist_file<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.blocklisted_files.insert(arg); + self + } + /// Treat the given type as opaque in the generated bindings. Regular /// expressions are supported. /// @@ -1669,6 +1677,10 @@ struct BindgenOptions { /// blocklisted and should not appear in the generated code. blocklisted_items: RegexSet, + /// The set of files whose contents should be blocklisted and should not + /// appear in the generated code. + blocklisted_files: RegexSet, + /// The set of types that should be treated as opaque structures in the /// generated code. opaque_types: RegexSet, @@ -1982,6 +1994,7 @@ impl BindgenOptions { &mut self.blocklisted_types, &mut self.blocklisted_functions, &mut self.blocklisted_items, + &mut self.blocklisted_files, &mut self.opaque_types, &mut self.bitfield_enums, &mut self.constified_enums, @@ -2029,6 +2042,7 @@ impl Default for BindgenOptions { blocklisted_types: Default::default(), blocklisted_functions: Default::default(), blocklisted_items: Default::default(), + blocklisted_files: Default::default(), opaque_types: Default::default(), rustfmt_path: Default::default(), depfile: Default::default(), diff --git a/src/options.rs b/src/options.rs index 9aac5dae..bc7431c5 100644 --- a/src/options.rs +++ b/src/options.rs @@ -164,6 +164,14 @@ where .takes_value(true) .multiple(true) .number_of_values(1), + Arg::with_name("blocklist-file") + .alias("blacklist-file") + .long("blocklist-file") + .help("Mark all contents of <path> as hidden.") + .value_name("path") + .takes_value(true) + .multiple(true) + .number_of_values(1), Arg::with_name("no-layout-tests") .long("no-layout-tests") .help("Avoid generating layout tests for any type."), @@ -630,6 +638,12 @@ where } } + if let Some(hidden_files) = matches.values_of("blocklist-file") { + for file in hidden_files { + builder = builder.blocklist_file(file); + } + } + if matches.is_present("builtins") { builder = builder.emit_builtins(); } |