summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-11-21 13:55:23 +0100
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-11-21 13:58:16 +0100
commit12a191e6968f1761eb3f4bbaf89a94312634734d (patch)
tree552a0b21b70d9af697275bb75aedc8ee8bcd3d50
parent1a8a2ac1c325487be455b434749c0b246f27e242 (diff)
codegen: Fix whitelisting inside namespaces.
-rw-r--r--libbindgen/src/codegen/mod.rs46
-rw-r--r--libbindgen/src/ir/context.rs2
-rw-r--r--libbindgen/tests/expectations/tests/duplicated_constants_in_ns.rs3
-rw-r--r--libbindgen/tests/expectations/tests/namespace.rs5
-rw-r--r--libbindgen/tests/expectations/tests/template_alias_namespace.rs3
-rw-r--r--libbindgen/tests/expectations/tests/whitelist-namespaces-basic.rs31
-rw-r--r--libbindgen/tests/expectations/tests/whitelist-namespaces.rs44
-rw-r--r--libbindgen/tests/headers/whitelist-namespaces-basic.hpp10
-rw-r--r--libbindgen/tests/headers/whitelist-namespaces.hpp10
9 files changed, 138 insertions, 16 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs
index 6c8a36f7..a522d887 100644
--- a/libbindgen/src/codegen/mod.rs
+++ b/libbindgen/src/codegen/mod.rs
@@ -33,7 +33,7 @@ fn root_import(ctx: &BindgenContext) -> P<ast::Item> {
assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up");
let root = ctx.root_module().canonical_name(ctx);
let root_ident = ctx.rust_ident(&root);
- quote_item!(ctx.ext_cx(), use $root_ident;).unwrap()
+ quote_item!(ctx.ext_cx(), #[allow(unused_imports)] use $root_ident;).unwrap()
}
struct CodegenResult {
@@ -217,6 +217,7 @@ trait CodeGenerator {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
extra: &Self::Extra);
}
@@ -226,6 +227,7 @@ impl CodeGenerator for Item {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
_extra: &()) {
if self.is_hidden(ctx) || result.seen(self.id()) {
debug!("<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
@@ -244,18 +246,18 @@ impl CodeGenerator for Item {
return;
}
- module.codegen(ctx, result, self);
+ module.codegen(ctx, result, whitelisted_items, self);
}
ItemKind::Function(ref fun) => {
if !ctx.options().ignore_functions {
- fun.codegen(ctx, result, self);
+ fun.codegen(ctx, result, whitelisted_items, self);
}
}
ItemKind::Var(ref var) => {
- var.codegen(ctx, result, self);
+ var.codegen(ctx, result, whitelisted_items, self);
}
ItemKind::Type(ref ty) => {
- ty.codegen(ctx, result, self);
+ ty.codegen(ctx, result, whitelisted_items, self);
}
}
}
@@ -267,12 +269,14 @@ impl CodeGenerator for Module {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
item: &Item) {
debug!("<Module as CodeGenerator>::codegen: item = {:?}", item);
if !ctx.options().enable_cxx_namespaces {
for child in self.children() {
- ctx.resolve_item(*child).codegen(ctx, result, &());
+ ctx.resolve_item(*child)
+ .codegen(ctx, result, whitelisted_items, &());
}
return;
}
@@ -280,7 +284,10 @@ impl CodeGenerator for Module {
let inner_items = result.inner(|result| {
result.push(root_import(ctx));
for child in self.children() {
- ctx.resolve_item(*child).codegen(ctx, result, &());
+ if whitelisted_items.contains(child) {
+ ctx.resolve_item(*child)
+ .codegen(ctx, result, whitelisted_items, &());
+ }
}
});
@@ -304,6 +311,7 @@ impl CodeGenerator for Var {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ _whitelisted_items: &ItemSet,
item: &Item) {
use ir::var::VarType;
debug!("<Var as CodeGenerator>::codegen: item = {:?}", item);
@@ -394,6 +402,7 @@ impl CodeGenerator for Type {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
item: &Item) {
debug!("<Type as CodeGenerator>::codegen: item = {:?}", item);
@@ -415,12 +424,12 @@ impl CodeGenerator for Type {
// converted to rust types in fields, arguments, and such.
return;
}
- TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item),
+ TypeKind::Comp(ref ci) => ci.codegen(ctx, result, whitelisted_items, item),
TypeKind::TemplateAlias(inner, _) => {
// NB: The inner Alias will pick the correct
// applicable_template_args.
let inner_item = ctx.resolve_item(inner);
- inner_item.expect_type().codegen(ctx, result, inner_item);
+ inner_item.expect_type().codegen(ctx, result, whitelisted_items, inner_item);
}
TypeKind::Alias(ref spelling, inner) => {
let inner_item = ctx.resolve_item(inner);
@@ -478,7 +487,7 @@ impl CodeGenerator for Type {
let typedef = generics.build().build_ty(inner_rust_type);
result.push(typedef)
}
- TypeKind::Enum(ref ei) => ei.codegen(ctx, result, item),
+ TypeKind::Enum(ref ei) => ei.codegen(ctx, result, whitelisted_items, item),
ref u @ TypeKind::UnresolvedTypeRef(..) => {
unreachable!("Should have been resolved after parsing {:?}!", u)
}
@@ -513,6 +522,7 @@ impl<'a> CodeGenerator for Vtable<'a> {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ _whitelisted_items: &ItemSet,
item: &Item) {
assert_eq!(item.id(), self.item_id);
// For now, generate an empty struct, later we should generate function
@@ -646,6 +656,7 @@ impl CodeGenerator for CompInfo {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
item: &Item) {
use aster::struct_field::StructFieldBuilder;
@@ -732,7 +743,7 @@ impl CodeGenerator for CompInfo {
if self.needs_explicit_vtable(ctx) {
let vtable =
Vtable::new(item.id(), self.methods(), self.base_members());
- vtable.codegen(ctx, result, item);
+ vtable.codegen(ctx, result, whitelisted_items, item);
let vtable_type = vtable.to_rust_ty(ctx).to_ptr(true, ctx.span());
@@ -1051,7 +1062,7 @@ impl CodeGenerator for CompInfo {
for ty in self.inner_types() {
let child_item = ctx.resolve_item(*ty);
// assert_eq!(child_item.parent_id(), item.id());
- child_item.codegen(ctx, result, &());
+ child_item.codegen(ctx, result, whitelisted_items, &());
}
// NOTE: Some unexposed attributes (like alignment attributes) may
@@ -1064,7 +1075,7 @@ impl CodeGenerator for CompInfo {
if applicable_template_args.is_empty() && !self.found_unknown_attr() {
for var in self.inner_vars() {
- ctx.resolve_item(*var).codegen(ctx, result, &());
+ ctx.resolve_item(*var).codegen(ctx, result, whitelisted_items, &());
}
if let Some(layout) = layout {
@@ -1094,6 +1105,7 @@ impl CodeGenerator for CompInfo {
&mut methods,
&mut method_names,
result,
+ whitelisted_items,
item);
}
}
@@ -1145,6 +1157,7 @@ trait MethodCodegen {
methods: &mut Vec<ast::ImplItem>,
method_names: &mut HashMap<String, usize>,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
parent: &Item);
}
@@ -1154,6 +1167,7 @@ impl MethodCodegen for Method {
methods: &mut Vec<ast::ImplItem>,
method_names: &mut HashMap<String, usize>,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
_parent: &Item) {
if ctx.options().ignore_methods {
return;
@@ -1163,7 +1177,7 @@ impl MethodCodegen for Method {
return; // FIXME
}
// First of all, output the actual function.
- ctx.resolve_item(self.signature()).codegen(ctx, result, &());
+ ctx.resolve_item(self.signature()).codegen(ctx, result, whitelisted_items, &());
let function_item = ctx.resolve_item(self.signature());
let function = function_item.expect_function();
@@ -1411,6 +1425,7 @@ impl CodeGenerator for Enum {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ _whitelisted_items: &ItemSet,
item: &Item) {
debug!("<Enum as CodeGenerator>::codegen: item = {:?}", item);
@@ -1852,6 +1867,7 @@ impl CodeGenerator for Function {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ _whitelisted_items: &ItemSet,
item: &Item) {
debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
@@ -1963,7 +1979,7 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
// need to take responsibility for generating it.
if item.is_toplevel(context) ||
!ancestor_is_whitelisted(context, &whitelisted_items, id) {
- item.codegen(context, &mut result, &());
+ item.codegen(context, &mut result, &whitelisted_items, &());
}
}
diff --git a/libbindgen/src/ir/context.rs b/libbindgen/src/ir/context.rs
index bda3e3c8..b7754a40 100644
--- a/libbindgen/src/ir/context.rs
+++ b/libbindgen/src/ir/context.rs
@@ -938,7 +938,7 @@ impl<'ctx> BindgenContext<'ctx> {
let name = item.canonical_name(self);
match *item.kind() {
- ItemKind::Module(..) => false,
+ ItemKind::Module(..) => self.options().enable_cxx_namespaces,
ItemKind::Function(_) => {
self.options().whitelisted_functions.matches(&name)
}
diff --git a/libbindgen/tests/expectations/tests/duplicated_constants_in_ns.rs b/libbindgen/tests/expectations/tests/duplicated_constants_in_ns.rs
index cb69890c..3acc53e8 100644
--- a/libbindgen/tests/expectations/tests/duplicated_constants_in_ns.rs
+++ b/libbindgen/tests/expectations/tests/duplicated_constants_in_ns.rs
@@ -5,12 +5,15 @@
pub mod root {
+ #[allow(unused_imports)]
use root;
pub mod foo {
+ #[allow(unused_imports)]
use root;
pub const FOO: ::std::os::raw::c_int = 4;
}
pub mod bar {
+ #[allow(unused_imports)]
use root;
pub const FOO: ::std::os::raw::c_int = 5;
}
diff --git a/libbindgen/tests/expectations/tests/namespace.rs b/libbindgen/tests/expectations/tests/namespace.rs
index bc8bae68..abb48204 100644
--- a/libbindgen/tests/expectations/tests/namespace.rs
+++ b/libbindgen/tests/expectations/tests/namespace.rs
@@ -5,12 +5,14 @@
pub mod root {
+ #[allow(unused_imports)]
use root;
extern "C" {
#[link_name = "_Z9top_levelv"]
pub fn top_level();
}
pub mod whatever {
+ #[allow(unused_imports)]
use root;
pub type whatever_int_t = ::std::os::raw::c_int;
extern "C" {
@@ -19,8 +21,10 @@ pub mod root {
}
}
pub mod _bindgen_mod_id_13 {
+ #[allow(unused_imports)]
use root;
pub mod empty {
+ #[allow(unused_imports)]
use root;
}
extern "C" {
@@ -50,6 +54,7 @@ pub mod root {
pub m_c_arr: [T; 10usize],
}
pub mod w {
+ #[allow(unused_imports)]
use root;
pub type whatever_int_t = ::std::os::raw::c_uint;
#[repr(C)]
diff --git a/libbindgen/tests/expectations/tests/template_alias_namespace.rs b/libbindgen/tests/expectations/tests/template_alias_namespace.rs
index 475c2b05..36806d44 100644
--- a/libbindgen/tests/expectations/tests/template_alias_namespace.rs
+++ b/libbindgen/tests/expectations/tests/template_alias_namespace.rs
@@ -5,10 +5,13 @@
pub mod root {
+ #[allow(unused_imports)]
use root;
pub mod JS {
+ #[allow(unused_imports)]
use root;
pub mod detail {
+ #[allow(unused_imports)]
use root;
pub type Wrapped<T> = T;
}
diff --git a/libbindgen/tests/expectations/tests/whitelist-namespaces-basic.rs b/libbindgen/tests/expectations/tests/whitelist-namespaces-basic.rs
new file mode 100644
index 00000000..8806cbf4
--- /dev/null
+++ b/libbindgen/tests/expectations/tests/whitelist-namespaces-basic.rs
@@ -0,0 +1,31 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+pub mod root {
+ #[allow(unused_imports)]
+ use root;
+ pub mod outer {
+ #[allow(unused_imports)]
+ use root;
+ pub mod inner {
+ #[allow(unused_imports)]
+ use root;
+ #[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct Helper {
+ pub _address: u8,
+ }
+ #[test]
+ fn bindgen_test_layout_Helper() {
+ assert_eq!(::std::mem::size_of::<Helper>() , 1usize);
+ assert_eq!(::std::mem::align_of::<Helper>() , 1usize);
+ }
+ impl Clone for Helper {
+ fn clone(&self) -> Self { *self }
+ }
+ }
+ }
+}
diff --git a/libbindgen/tests/expectations/tests/whitelist-namespaces.rs b/libbindgen/tests/expectations/tests/whitelist-namespaces.rs
new file mode 100644
index 00000000..42cccdee
--- /dev/null
+++ b/libbindgen/tests/expectations/tests/whitelist-namespaces.rs
@@ -0,0 +1,44 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+pub mod root {
+ #[allow(unused_imports)]
+ use root;
+ pub mod outer {
+ #[allow(unused_imports)]
+ use root;
+ pub mod inner {
+ #[allow(unused_imports)]
+ use root;
+ #[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct Helper {
+ pub _address: u8,
+ }
+ #[test]
+ fn bindgen_test_layout_Helper() {
+ assert_eq!(::std::mem::size_of::<Helper>() , 1usize);
+ assert_eq!(::std::mem::align_of::<Helper>() , 1usize);
+ }
+ impl Clone for Helper {
+ fn clone(&self) -> Self { *self }
+ }
+ }
+ #[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct Test {
+ pub helper: root::outer::inner::Helper,
+ }
+ #[test]
+ fn bindgen_test_layout_Test() {
+ assert_eq!(::std::mem::size_of::<Test>() , 1usize);
+ assert_eq!(::std::mem::align_of::<Test>() , 1usize);
+ }
+ impl Clone for Test {
+ fn clone(&self) -> Self { *self }
+ }
+ }
+}
diff --git a/libbindgen/tests/headers/whitelist-namespaces-basic.hpp b/libbindgen/tests/headers/whitelist-namespaces-basic.hpp
new file mode 100644
index 00000000..b631d290
--- /dev/null
+++ b/libbindgen/tests/headers/whitelist-namespaces-basic.hpp
@@ -0,0 +1,10 @@
+// bindgen-flags: --enable-cxx-namespaces --whitelist-type '.*Helper'
+
+namespace outer {
+ namespace inner {
+ struct Helper {};
+ }
+ struct Test {
+ inner::Helper helper;
+ };
+}
diff --git a/libbindgen/tests/headers/whitelist-namespaces.hpp b/libbindgen/tests/headers/whitelist-namespaces.hpp
new file mode 100644
index 00000000..d34cbe94
--- /dev/null
+++ b/libbindgen/tests/headers/whitelist-namespaces.hpp
@@ -0,0 +1,10 @@
+// bindgen-flags: --enable-cxx-namespaces --whitelist-type '.*'
+
+namespace outer {
+ namespace inner {
+ struct Helper {};
+ }
+ struct Test {
+ inner::Helper helper;
+ };
+}