summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbindgen/src/codegen/mod.rs77
-rw-r--r--libbindgen/src/ir/context.rs35
-rw-r--r--libbindgen/src/ir/item.rs19
-rw-r--r--libbindgen/tests/expectations/tests/maddness-is-avoidable.rs20
-rw-r--r--libbindgen/tests/expectations/tests/module-whitelisted.rs23
-rw-r--r--libbindgen/tests/expectations/tests/namespace.rs12
-rw-r--r--libbindgen/tests/expectations/tests/replace_use.rs28
-rw-r--r--libbindgen/tests/expectations/tests/whitelist_fix.rs10
-rw-r--r--libbindgen/tests/headers/maddness-is-avoidable.hpp9
-rw-r--r--libbindgen/tests/headers/module-whitelisted.hpp2
-rw-r--r--libbindgen/tests/headers/replace_use.hpp15
-rw-r--r--libbindgen/tests/headers/whitelist-namespaces-basic.hpp2
-rw-r--r--libbindgen/tests/headers/whitelist_fix.hpp4
13 files changed, 169 insertions, 87 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs
index a3fefcc7..0469a5be 100644
--- a/libbindgen/src/codegen/mod.rs
+++ b/libbindgen/src/codegen/mod.rs
@@ -242,11 +242,6 @@ impl CodeGenerator for Item {
match *self.kind() {
ItemKind::Module(ref module) => {
- if !ctx.options().enable_cxx_namespaces &&
- self.id() == ctx.root_module() {
- return;
- }
-
module.codegen(ctx, result, whitelisted_items, self);
}
ItemKind::Function(ref fun) => {
@@ -274,22 +269,28 @@ impl CodeGenerator for Module {
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, whitelisted_items, &());
+ let codegen_self = |result: &mut CodegenResult| {
+ // FIXME: This could be less expensive, I guess.
+ for &whitelisted_item in whitelisted_items {
+ if whitelisted_item == item.id() {
+ continue;
+ }
+
+ let child = ctx.resolve_item(whitelisted_item);
+ if child.parent_id() == item.id() {
+ child.codegen(ctx, result, whitelisted_items, &());
+ }
}
+ };
+
+ if !ctx.options().enable_cxx_namespaces {
+ codegen_self(result);
return;
}
let inner_items = result.inner(|result| {
result.push(root_import(ctx));
- for child in self.children() {
- if whitelisted_items.contains(child) {
- ctx.resolve_item(*child)
- .codegen(ctx, result, whitelisted_items, &());
- }
- }
+ codegen_self(result);
});
let module = ast::ItemKind::Mod(ast::Mod {
@@ -428,13 +429,12 @@ impl CodeGenerator for Type {
TypeKind::Comp(ref ci) => {
ci.codegen(ctx, result, whitelisted_items, item)
}
+ // NB: The inner Alias will be generated and pick the correct
+ // applicable_template_args.
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, whitelisted_items, inner_item);
- }
+ ctx.resolve_item(inner)
+ .codegen(ctx, result, whitelisted_items, &())
+ },
TypeKind::Alias(ref spelling, inner) => {
let inner_item = ctx.resolve_item(inner);
let name = item.canonical_name(ctx);
@@ -1964,27 +1964,6 @@ impl CodeGenerator for Function {
}
}
-// Return true if any of the ancestors of `id` are in the whitelisted items set,
-// false otherwise.
-fn ancestor_is_whitelisted(ctx: &BindgenContext,
- whitelisted_items: &ItemSet,
- id: ItemId)
- -> bool {
- let item = ctx.resolve_item(id);
- let mut last = id;
- let mut current = item.parent_id();
-
- while last != current {
- if whitelisted_items.contains(&current) {
- return true;
- }
- last = current;
- current = ctx.resolve_item(current).parent_id();
- }
-
- false
-}
-
pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
context.gen(|context| {
let mut result = CodegenResult::new();
@@ -2000,18 +1979,8 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
}
}
- for &id in whitelisted_items.iter() {
- let item = context.resolve_item(id);
-
- // Non-toplevel items' parents are responsible one for generating
- // their children. However, if we find an orphaned reference to a
- // non-toplevel item whose parent is not in our whitelisted set, we
- // need to take responsibility for generating it.
- if item.is_toplevel(context) ||
- !ancestor_is_whitelisted(context, &whitelisted_items, id) {
- item.codegen(context, &mut result, &whitelisted_items, &());
- }
- }
+ context.resolve_item(context.root_module())
+ .codegen(context, &mut result, &whitelisted_items, &());
let saw_union = result.saw_union;
let mut result = result.items;
diff --git a/libbindgen/src/ir/context.rs b/libbindgen/src/ir/context.rs
index 76e27841..e599160e 100644
--- a/libbindgen/src/ir/context.rs
+++ b/libbindgen/src/ir/context.rs
@@ -10,7 +10,7 @@ use std::collections::{HashMap, hash_map};
use std::collections::btree_map::{self, BTreeMap};
use std::fmt;
use super::int::IntKind;
-use super::item::{Item, ItemCanonicalName};
+use super::item::Item;
use super::item_kind::ItemKind;
use super::module::Module;
use super::ty::{FloatKind, Type, TypeKind};
@@ -938,11 +938,9 @@ impl<'ctx> BindgenContext<'ctx> {
return true;
}
- let name = item.canonical_name(self);
+ let name = item.real_canonical_name(self, false, true);
match *item.kind() {
- ItemKind::Module(..) => {
- self.options().enable_cxx_namespaces
- }
+ ItemKind::Module(..) => true,
ItemKind::Function(_) => {
self.options().whitelisted_functions.matches(&name)
}
@@ -954,18 +952,21 @@ impl<'ctx> BindgenContext<'ctx> {
return true;
}
- // Unnamed top-level enums are special and we whitelist
- // them via the `whitelisted_vars` filter, since they're
- // effectively top-level constants, and there's no way
- // for them to be referenced consistently.
- if let TypeKind::Enum(ref enum_) = *ty.kind() {
- if ty.name().is_none() &&
- enum_.variants().iter().any(|variant| {
- self.options()
- .whitelisted_vars
- .matches(&variant.name())
- }) {
- return true;
+ if self.resolve_item(item.parent_id()).is_module() {
+ // Unnamed top-level enums are special and we
+ // whitelist them via the `whitelisted_vars` filter,
+ // since they're effectively top-level constants,
+ // and there's no way for them to be referenced
+ // consistently.
+ if let TypeKind::Enum(ref enum_) = *ty.kind() {
+ if ty.name().is_none() &&
+ enum_.variants().iter().any(|variant| {
+ self.options()
+ .whitelisted_vars
+ .matches(&variant.name())
+ }) {
+ return true;
+ }
}
}
diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs
index b857acf9..1f15ff0f 100644
--- a/libbindgen/src/ir/item.rs
+++ b/libbindgen/src/ir/item.rs
@@ -532,6 +532,14 @@ impl Item {
self.as_type().map_or(false, |ty| ty.is_type_ref())
}
+ /// Is this item a var type?
+ pub fn is_var(&self) -> bool {
+ match *self.kind() {
+ ItemKind::Var(..) => true,
+ _ => false,
+ }
+ }
+
/// Get the target item id for name generation.
fn name_target(&self,
ctx: &BindgenContext,
@@ -664,6 +672,14 @@ impl Item {
for_name_checking: bool)
-> String {
let target = ctx.resolve_item(self.name_target(ctx, for_name_checking));
+
+ // Short-circuit if the target has an override, and just use that.
+ if !for_name_checking {
+ if let Some(other) = target.annotations.use_instead_of() {
+ return other.to_owned();
+ }
+ }
+
let base_name = target.base_name(ctx, for_name_checking);
// Named template type arguments are never namespaced, and never
@@ -1135,9 +1151,6 @@ impl ItemCanonicalName for Item {
fn canonical_name(&self, ctx: &BindgenContext) -> String {
debug_assert!(ctx.in_codegen_phase(),
"You're not supposed to call this yet");
- if let Some(other_canon_type) = self.annotations.use_instead_of() {
- return other_canon_type.to_owned();
- }
if self.canonical_name_cache.borrow().is_none() {
*self.canonical_name_cache.borrow_mut() =
Some(self.real_canonical_name(ctx,
diff --git a/libbindgen/tests/expectations/tests/maddness-is-avoidable.rs b/libbindgen/tests/expectations/tests/maddness-is-avoidable.rs
new file mode 100644
index 00000000..d31345ba
--- /dev/null
+++ b/libbindgen/tests/expectations/tests/maddness-is-avoidable.rs
@@ -0,0 +1,20 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RefPtr<T> {
+ pub _address: u8,
+ pub _phantom_0: ::std::marker::PhantomData<T>,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RefPtr_Proxy<T, R, Args> {
+ pub _address: u8,
+ pub _phantom_0: ::std::marker::PhantomData<T>,
+ pub _phantom_1: ::std::marker::PhantomData<R>,
+ pub _phantom_2: ::std::marker::PhantomData<Args>,
+}
diff --git a/libbindgen/tests/expectations/tests/module-whitelisted.rs b/libbindgen/tests/expectations/tests/module-whitelisted.rs
new file mode 100644
index 00000000..7e63c8c8
--- /dev/null
+++ b/libbindgen/tests/expectations/tests/module-whitelisted.rs
@@ -0,0 +1,23 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+pub mod root {
+ #[allow(unused_imports)]
+ use root;
+ #[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct Test {
+ pub _address: u8,
+ }
+ #[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/expectations/tests/namespace.rs b/libbindgen/tests/expectations/tests/namespace.rs
index abb48204..54bc08dc 100644
--- a/libbindgen/tests/expectations/tests/namespace.rs
+++ b/libbindgen/tests/expectations/tests/namespace.rs
@@ -76,15 +76,3 @@ pub mod root {
}
}
}
-extern "C" {
- #[link_name = "_Z9top_levelv"]
- pub fn top_level();
-}
-#[repr(C)]
-#[derive(Debug)]
-pub struct C<T> {
- pub _base: root::_bindgen_mod_id_13::A,
- pub m_c: T,
- pub m_c_ptr: *mut T,
- pub m_c_arr: [T; 10usize],
-}
diff --git a/libbindgen/tests/expectations/tests/replace_use.rs b/libbindgen/tests/expectations/tests/replace_use.rs
new file mode 100644
index 00000000..f4fee442
--- /dev/null
+++ b/libbindgen/tests/expectations/tests/replace_use.rs
@@ -0,0 +1,28 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+/**
+ * <div rustbindgen replaces="nsTArray"></div>
+ */
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nsTArray<T> {
+ pub y: ::std::os::raw::c_uint,
+ pub _phantom_0: ::std::marker::PhantomData<T>,
+}
+#[repr(C)]
+#[derive(Debug, Copy)]
+pub struct Test {
+ pub a: nsTArray<::std::os::raw::c_long>,
+}
+#[test]
+fn bindgen_test_layout_Test() {
+ assert_eq!(::std::mem::size_of::<Test>() , 4usize);
+ assert_eq!(::std::mem::align_of::<Test>() , 4usize);
+}
+impl Clone for Test {
+ fn clone(&self) -> Self { *self }
+}
diff --git a/libbindgen/tests/expectations/tests/whitelist_fix.rs b/libbindgen/tests/expectations/tests/whitelist_fix.rs
new file mode 100644
index 00000000..9e26e1be
--- /dev/null
+++ b/libbindgen/tests/expectations/tests/whitelist_fix.rs
@@ -0,0 +1,10 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+pub enum Test {}
+
+extern "C" {
+ pub fn Servo_Test(a: *mut Test);
+}
diff --git a/libbindgen/tests/headers/maddness-is-avoidable.hpp b/libbindgen/tests/headers/maddness-is-avoidable.hpp
new file mode 100644
index 00000000..46d7495e
--- /dev/null
+++ b/libbindgen/tests/headers/maddness-is-avoidable.hpp
@@ -0,0 +1,9 @@
+// bindgen-flags: --blacklist-type RefPtr_Proxy_member_function
+
+template<typename T>
+class RefPtr {
+ template<typename R, typename... Args>
+ class Proxy {
+ typedef R (T::*member_function)(Args...);
+ };
+};
diff --git a/libbindgen/tests/headers/module-whitelisted.hpp b/libbindgen/tests/headers/module-whitelisted.hpp
new file mode 100644
index 00000000..f41e874e
--- /dev/null
+++ b/libbindgen/tests/headers/module-whitelisted.hpp
@@ -0,0 +1,2 @@
+// bindgen-flags: --enable-cxx-namespaces
+struct Test {};
diff --git a/libbindgen/tests/headers/replace_use.hpp b/libbindgen/tests/headers/replace_use.hpp
new file mode 100644
index 00000000..de44eb19
--- /dev/null
+++ b/libbindgen/tests/headers/replace_use.hpp
@@ -0,0 +1,15 @@
+template<typename T>
+struct nsTArray {
+ int x;
+};
+/**
+ * <div rustbindgen replaces="nsTArray"></div>
+ */
+template<typename T>
+struct nsTArray_Simple {
+ unsigned int y;
+};
+
+struct Test {
+ nsTArray<long> a;
+};
diff --git a/libbindgen/tests/headers/whitelist-namespaces-basic.hpp b/libbindgen/tests/headers/whitelist-namespaces-basic.hpp
index b631d290..abe9dc11 100644
--- a/libbindgen/tests/headers/whitelist-namespaces-basic.hpp
+++ b/libbindgen/tests/headers/whitelist-namespaces-basic.hpp
@@ -1,4 +1,4 @@
-// bindgen-flags: --enable-cxx-namespaces --whitelist-type '.*Helper'
+// bindgen-flags: --enable-cxx-namespaces --whitelist-type outer_inner_Helper
namespace outer {
namespace inner {
diff --git a/libbindgen/tests/headers/whitelist_fix.hpp b/libbindgen/tests/headers/whitelist_fix.hpp
new file mode 100644
index 00000000..d0abda54
--- /dev/null
+++ b/libbindgen/tests/headers/whitelist_fix.hpp
@@ -0,0 +1,4 @@
+// bindgen-flags: --whitelist-function 'Servo_.*' --blacklist-type Test --raw-line "pub enum Test {}"
+
+struct Test {};
+extern "C" void Servo_Test(Test* a);