summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2016-11-03 13:01:41 -0700
committerNick Fitzgerald <fitzgen@gmail.com>2016-11-03 14:18:06 -0700
commit8041ebfdbcf11fc327b6b4bfd56a243a16fc80d7 (patch)
treec0fabf1c80c5d45fbcfd3ec396e175bb0f67728e
parenteff92920d42eb87a9dedc5fb32c02aac382a51c5 (diff)
Allow template aliases to be considered for replacement
-rw-r--r--src/ir/context.rs24
-rw-r--r--src/ir/item.rs10
-rw-r--r--tests/expectations/replace_template_alias.rs15
-rw-r--r--tests/headers/replace_template_alias.hpp23
4 files changed, 57 insertions, 15 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs
index b51a2cb9..9ffb1b7a 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -320,23 +320,27 @@ impl<'ctx> BindgenContext<'ctx> {
let mut replacements = vec![];
for (id, item) in self.items.iter() {
+ // Calls to `canonical_name` are expensive, so eagerly filter out
+ // items that cannot be replaced.
let ty = match item.kind().as_type() {
Some(ty) => ty,
None => continue,
};
- // canonical_name calls are expensive.
- let ci = match ty.as_comp() {
- Some(ci) => ci,
- None => continue,
- };
-
- if ci.is_template_specialization() {
- continue;
+ match *ty.kind() {
+ TypeKind::Comp(ref ci) if !ci.is_template_specialization() => {}
+ TypeKind::TemplateAlias(_, _) |
+ TypeKind::Alias(_, _) => {}
+ _ => continue,
}
- if let Some(replacement) = self.replacements
- .get(&item.canonical_name(self)) {
+ let name = item.real_canonical_name(self,
+ self.options()
+ .enable_cxx_namespaces,
+ true);
+ let replacement = self.replacements.get(&name);
+
+ if let Some(replacement) = replacement {
if replacement != id {
// We set this just after parsing the annotation. It's
// very unlikely, but this can happen.
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 690f4222..d986bb32 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -539,11 +539,11 @@ impl Item {
///
/// This name should be derived from the immutable state contained in the
/// type and the parent chain, since it should be consistent.
- fn real_canonical_name(&self,
- ctx: &BindgenContext,
- count_namespaces: bool,
- for_name_checking: bool)
- -> String {
+ pub fn real_canonical_name(&self,
+ ctx: &BindgenContext,
+ count_namespaces: bool,
+ for_name_checking: bool)
+ -> String {
let base_name = match *self.kind() {
ItemKind::Type(ref ty) => {
match *ty.kind() {
diff --git a/tests/expectations/replace_template_alias.rs b/tests/expectations/replace_template_alias.rs
new file mode 100644
index 00000000..61a2fbcc
--- /dev/null
+++ b/tests/expectations/replace_template_alias.rs
@@ -0,0 +1,15 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct Rooted<T> {
+ pub ptr: MaybeWrapped<T>,
+}
+/// But the replacement type does use T!
+///
+/// <div rustbindgen replaces="MaybeWrapped" />
+pub type MaybeWrapped<T> = T;
diff --git a/tests/headers/replace_template_alias.hpp b/tests/headers/replace_template_alias.hpp
new file mode 100644
index 00000000..6ceae4e5
--- /dev/null
+++ b/tests/headers/replace_template_alias.hpp
@@ -0,0 +1,23 @@
+// bindgen-flags: -- --std=c++14
+
+namespace JS {
+namespace detail {
+
+/// Notice how this doesn't use T.
+template <typename T>
+using MaybeWrapped = int;
+
+}
+
+template <typename T>
+class Rooted {
+ detail::MaybeWrapped<T> ptr;
+};
+
+}
+
+/// But the replacement type does use T!
+///
+/// <div rustbindgen replaces="MaybeWrapped" />
+template <typename T>
+using replaces_MaybeWrapped = T;