summaryrefslogtreecommitdiff
path: root/libbindgen/src
diff options
context:
space:
mode:
Diffstat (limited to 'libbindgen/src')
-rw-r--r--libbindgen/src/clang.rs13
-rw-r--r--libbindgen/src/ir/comp.rs18
-rw-r--r--libbindgen/src/ir/context.rs6
-rw-r--r--libbindgen/src/ir/item.rs23
-rw-r--r--libbindgen/src/ir/ty.rs2
-rw-r--r--libbindgen/src/lib.rs23
6 files changed, 68 insertions, 17 deletions
diff --git a/libbindgen/src/clang.rs b/libbindgen/src/clang.rs
index 72069644..7c6d3199 100644
--- a/libbindgen/src/clang.rs
+++ b/libbindgen/src/clang.rs
@@ -760,6 +760,19 @@ impl Type {
pub fn is_valid_and_exposed(&self) -> bool {
self.is_valid() && self.kind() != CXType_Unexposed
}
+
+ /// Is this type a fully specialized template?
+ pub fn is_fully_specialized_template(&self) -> bool {
+ // Yep, the spelling of this containing type-parameter is extremely
+ // nasty... But can happen in <type_traits>. Unfortunately I couldn't
+ // reduce it enough :(
+ !self.spelling().contains("type-parameter") &&
+ self.template_args()
+ .map_or(false, |mut args| {
+ args.len() > 0 &&
+ !args.any(|t| t.spelling().contains("type-parameter"))
+ })
+ }
}
/// An iterator for a type's template arguments.
diff --git a/libbindgen/src/ir/comp.rs b/libbindgen/src/ir/comp.rs
index d19d1209..d2ace023 100644
--- a/libbindgen/src/ir/comp.rs
+++ b/libbindgen/src/ir/comp.rs
@@ -498,17 +498,29 @@ impl CompInfo {
None => vec![],
Some(arg_types) => {
let num_arg_types = arg_types.len();
+ let mut specialization = true;
let args = arg_types.filter(|t| t.kind() != CXType_Invalid)
- .map(|t| Item::from_ty_or_ref(t, None, None, ctx))
+ .filter_map(|t| {
+ if t.spelling().starts_with("type-parameter") {
+ specialization = false;
+ None
+ } else {
+ Some(Item::from_ty_or_ref(t, None, None, ctx))
+ }
+ })
.collect::<Vec<_>>();
- if args.len() != num_arg_types {
+ if specialization && args.len() != num_arg_types {
ci.has_non_type_template_params = true;
warn!("warning: Template parameter is not a type");
}
- args
+ if specialization {
+ args
+ } else {
+ vec![]
+ }
}
};
diff --git a/libbindgen/src/ir/context.rs b/libbindgen/src/ir/context.rs
index 67db2a59..a0e57610 100644
--- a/libbindgen/src/ir/context.rs
+++ b/libbindgen/src/ir/context.rs
@@ -367,10 +367,8 @@ impl<'ctx> BindgenContext<'ctx> {
_ => continue,
}
- let name = item.real_canonical_name(self,
- self.options()
- .enable_cxx_namespaces,
- true);
+ let in_namespace = self.options().enable_cxx_namespaces;
+ let name = item.real_canonical_name(self, in_namespace, true);
let replacement = self.replacements.get(&name);
if let Some(replacement) = replacement {
diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs
index 1f15ff0f..1d643a45 100644
--- a/libbindgen/src/ir/item.rs
+++ b/libbindgen/src/ir/item.rs
@@ -688,14 +688,14 @@ impl Item {
return base_name;
}
- if within_namespace {
- return ctx.rust_mangle(&base_name).into_owned();
- }
-
// Concatenate this item's ancestors' names together.
let mut names: Vec<_> = target.parent_id()
.ancestors(ctx)
.filter(|id| *id != ctx.root_module())
+ .take_while(|id| {
+ // Stop iterating ancestors once we reach a namespace.
+ !within_namespace || !ctx.resolve_item(*id).is_module()
+ })
.map(|id| {
let item = ctx.resolve_item(id);
let target = ctx.resolve_item(item.name_target(ctx, false));
@@ -703,8 +703,13 @@ impl Item {
})
.filter(|name| !name.is_empty())
.collect();
+
names.reverse();
- names.push(base_name);
+
+ if !base_name.is_empty() {
+ names.push(base_name);
+ }
+
let name = names.join("_");
ctx.rust_mangle(&name).into_owned()
@@ -1152,11 +1157,11 @@ impl ItemCanonicalName for Item {
debug_assert!(ctx.in_codegen_phase(),
"You're not supposed to call this yet");
if self.canonical_name_cache.borrow().is_none() {
+ let in_namespace = ctx.options().enable_cxx_namespaces ||
+ ctx.options().disable_name_namespacing;
+
*self.canonical_name_cache.borrow_mut() =
- Some(self.real_canonical_name(ctx,
- ctx.options()
- .enable_cxx_namespaces,
- false));
+ Some(self.real_canonical_name(ctx, in_namespace, false));
}
return self.canonical_name_cache.borrow().as_ref().unwrap().clone();
}
diff --git a/libbindgen/src/ir/ty.rs b/libbindgen/src/ir/ty.rs
index 7f01e388..33e20861 100644
--- a/libbindgen/src/ir/ty.rs
+++ b/libbindgen/src/ir/ty.rs
@@ -554,7 +554,7 @@ impl Type {
TypeKind::Function(signature)
// Same here, with template specialisations we can safely
// assume this is a Comp(..)
- } else if ty.template_args().map_or(false, |x| x.len() > 0) {
+ } else if ty.is_fully_specialized_template() {
debug!("Template specialization: {:?}", ty);
let complex =
CompInfo::from_ty(potential_id, ty, location, ctx)
diff --git a/libbindgen/src/lib.rs b/libbindgen/src/lib.rs
index 10961e36..f25c6cdf 100644
--- a/libbindgen/src/lib.rs
+++ b/libbindgen/src/lib.rs
@@ -243,6 +243,25 @@ impl Builder {
self
}
+ /// Disable auto-namespacing of names if namespaces are disabled.
+ ///
+ /// By default, if namespaces are disabled, bindgen tries to mangle the
+ /// names to from `foo::bar::Baz` to look like `foo_bar_Baz`, instead of
+ /// just `Baz`.
+ ///
+ /// This option disables that behavior.
+ ///
+ /// Note that this intentionally doesn't change the names using for
+ /// whitelisting and blacklisting, that should still be mangled with the
+ /// namespaces.
+ ///
+ /// Note, also, that using this option may cause duplicated names to be
+ /// generated.
+ pub fn disable_name_namespacing(mut self) -> Builder {
+ self.options.disable_name_namespacing = true;
+ self
+ }
+
/// Ignore functions.
pub fn ignore_functions(mut self) -> Builder {
self.options.ignore_functions = true;
@@ -341,6 +360,9 @@ pub struct BindgenOptions {
/// generated bindings.
pub enable_cxx_namespaces: bool,
+ /// True if we should avoid mangling names with namespaces.
+ pub disable_name_namespacing: bool,
+
/// True if we shold derive Debug trait implementations for C/C++ structures
/// and types.
pub derive_debug: bool,
@@ -400,6 +422,7 @@ impl Default for BindgenOptions {
ignore_methods: false,
derive_debug: true,
enable_cxx_namespaces: false,
+ disable_name_namespacing: false,
unstable_rust: true,
use_core: false,
ctypes_prefix: None,