summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-08-11 19:25:55 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-08-13 21:21:43 +0200
commitb2bed3068e6df239fbf49165b1374a2c8d9e92e0 (patch)
treed670b17c97339d95ce9aad9b1dda671bb69a57f9
parenta0176cd29d8d7e8eff9cb8ef16ed279f91949ace (diff)
ir: Sanitize base names more aggressively.
This fixes stylo build failures when template instantiations tests caused a rust compile error due to a bad test name. This commit makes names better sanitized, preventing similar errors in the future.
-rw-r--r--src/ir/context.rs8
-rw-r--r--src/ir/item.rs22
-rw-r--r--src/ir/ty.rs11
-rw-r--r--tests/expectations/tests/template.rs34
-rw-r--r--tests/headers/template.hpp5
5 files changed, 63 insertions, 17 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 5caebeda..a0663d8c 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -1452,13 +1452,7 @@ impl<'ctx> BindgenContext<'ctx> {
_ => return None,
};
- let mut spelling = ty.spelling();
- // avoid the allocation if possible
- if spelling.contains(' ') {
- // These names are used in generated test names,
- // they should be valid identifiers
- spelling = spelling.replace(' ', "_");
- }
+ let spelling = ty.spelling();
let is_const = ty.is_const();
let layout = ty.fallible_layout().ok();
let ty = Type::new(Some(spelling), layout, type_kind, is_const);
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 237618c8..156d4829 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -695,18 +695,32 @@ impl Item {
}
ItemKind::Type(ref ty) => {
let name = match *ty.kind() {
- TypeKind::ResolvedTypeRef(..) => panic!("should have resolved this in name_target()"),
+ TypeKind::ResolvedTypeRef(..) => {
+ panic!("should have resolved this in name_target()")
+ }
TypeKind::Pointer(inner) => {
ctx.resolve_item(inner)
.expect_type().name()
- .map(|name| format!("ptr_{}", name))
+ .map(|name| {
+ format!("ptr_{}", Type::sanitize_name(name))
+ })
}
TypeKind::Array(inner, length) => {
ctx.resolve_item(inner)
.expect_type().name()
- .map(|name| format!("array_{}_{}", name, length))
+ .map(|name| {
+ format!(
+ "array_{}_{}",
+ Type::sanitize_name(name),
+ length,
+ )
+ })
+ }
+ _ => {
+ ty.name()
+ .map(Type::sanitize_name)
+ .map(Into::into)
}
- _ => ty.name().map(ToOwned::to_owned)
};
name.unwrap_or_else(|| {
format!("_bindgen_ty_{}", self.exposed_id(ctx))
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 0af7b7c2..4a2b7668 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -13,6 +13,7 @@ use super::template::{AsTemplateParam, TemplateInstantiation, TemplateParameters
use super::traversal::{EdgeKind, Trace, Tracer};
use clang::{self, Cursor};
use parse::{ClangItemParser, ParseError, ParseResult};
+use std::borrow::Cow;
use std::io;
use std::mem;
@@ -272,6 +273,16 @@ impl Type {
clang::is_valid_identifier(name)
}
+ /// Takes `name`, and returns a suitable identifier representation for it.
+ pub fn sanitize_name<'a>(name: &'a str) -> Cow<'a, str> {
+ if Self::is_valid_identifier(name) {
+ return Cow::Borrowed(name)
+ }
+
+ let name = name.replace(|c| c == ' ' || c == ':' || c == '.' , "_");
+ Cow::Owned(name)
+ }
+
/// See safe_canonical_type.
pub fn canonical_type<'tr>(&'tr self,
ctx: &'tr BindgenContext)
diff --git a/tests/expectations/tests/template.rs b/tests/expectations/tests/template.rs
index 141af8fa..9cea4d97 100644
--- a/tests/expectations/tests/template.rs
+++ b/tests/expectations/tests/template.rs
@@ -29,10 +29,16 @@ extern "C" {
pub fn bar(foo: Foo<::std::os::raw::c_int>);
}
#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct mozilla_Foo {
+ _unused: [u8; 0],
+}
+#[repr(C)]
#[derive(Debug, Copy, Hash)]
pub struct C {
pub mB: B<::std::os::raw::c_uint>,
pub mBConstPtr: B<*const ::std::os::raw::c_int>,
+ pub mBConstStructPtr: B<*const mozilla_Foo>,
pub mBConst: B<::std::os::raw::c_int>,
pub mBVolatile: B<::std::os::raw::c_int>,
pub mBConstBool: B<bool>,
@@ -41,7 +47,7 @@ pub struct C {
}
#[test]
fn bindgen_test_layout_C() {
- assert_eq!(::std::mem::size_of::<C>() , 32usize , concat ! (
+ assert_eq!(::std::mem::size_of::<C>() , 40usize , concat ! (
"Size of: " , stringify ! ( C ) ));
assert_eq! (::std::mem::align_of::<C>() , 8usize , concat ! (
"Alignment of " , stringify ! ( C ) ));
@@ -55,28 +61,33 @@ fn bindgen_test_layout_C() {
"Alignment of field: " , stringify ! ( C ) , "::" , stringify
! ( mBConstPtr ) ));
assert_eq! (unsafe {
+ & ( * ( 0 as * const C ) ) . mBConstStructPtr as * const _ as
+ usize } , 16usize , concat ! (
+ "Alignment of field: " , stringify ! ( C ) , "::" , stringify
+ ! ( mBConstStructPtr ) ));
+ assert_eq! (unsafe {
& ( * ( 0 as * const C ) ) . mBConst as * const _ as usize } ,
- 16usize , concat ! (
+ 24usize , concat ! (
"Alignment of field: " , stringify ! ( C ) , "::" , stringify
! ( mBConst ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const C ) ) . mBVolatile as * const _ as usize
- } , 20usize , concat ! (
+ } , 28usize , concat ! (
"Alignment of field: " , stringify ! ( C ) , "::" , stringify
! ( mBVolatile ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const C ) ) . mBConstBool as * const _ as usize
- } , 24usize , concat ! (
+ } , 32usize , concat ! (
"Alignment of field: " , stringify ! ( C ) , "::" , stringify
! ( mBConstBool ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const C ) ) . mBConstChar as * const _ as usize
- } , 26usize , concat ! (
+ } , 34usize , concat ! (
"Alignment of field: " , stringify ! ( C ) , "::" , stringify
! ( mBConstChar ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const C ) ) . mBArray as * const _ as usize } ,
- 28usize , concat ! (
+ 36usize , concat ! (
"Alignment of field: " , stringify ! ( C ) , "::" , stringify
! ( mBArray ) ));
}
@@ -331,6 +342,17 @@ fn __bindgen_test_layout_B_open0_ptr_const_int_close0_instantiation() {
B<*const ::std::os::raw::c_int> ) ));
}
#[test]
+fn __bindgen_test_layout_B_open0_ptr_const_mozilla__Foo_close0_instantiation() {
+ assert_eq!(::std::mem::size_of::<B<*const mozilla_Foo>>() , 8usize ,
+ concat ! (
+ "Size of template specialization: " , stringify ! (
+ B<*const mozilla_Foo> ) ));
+ assert_eq!(::std::mem::align_of::<B<*const mozilla_Foo>>() , 8usize ,
+ concat ! (
+ "Alignment of template specialization: " , stringify ! (
+ B<*const mozilla_Foo> ) ));
+}
+#[test]
fn __bindgen_test_layout_B_open0_const_int_close0_instantiation() {
assert_eq!(::std::mem::size_of::<B<::std::os::raw::c_int>>() , 4usize ,
concat ! (
diff --git a/tests/headers/template.hpp b/tests/headers/template.hpp
index 4f543893..0f067053 100644
--- a/tests/headers/template.hpp
+++ b/tests/headers/template.hpp
@@ -12,9 +12,14 @@ template<typename T> class B {
void bar(Foo<int, int> foo);
+namespace mozilla {
+class Foo;
+};
+
struct C {
B<unsigned int> mB;
B<const int*> mBConstPtr;
+ B<const mozilla::Foo*> mBConstStructPtr;
B<const int> mBConst;
B<volatile int> mBVolatile;
B<const bool> mBConstBool;