summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/mod.rs8
-rw-r--r--src/ir/item.rs29
-rw-r--r--src/ir/ty.rs62
3 files changed, 89 insertions, 10 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 4ebc48bf..a5159c98 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -341,6 +341,12 @@ impl CodeGenerator for Type {
return;
}
TypeKind::Comp(ref ci) => ci.codegen(ctx, result, 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);
+ }
TypeKind::Alias(ref spelling, inner) => {
let inner_item = ctx.resolve_item(inner);
let name = item.canonical_name(ctx);
@@ -1361,6 +1367,7 @@ impl ToRustTy for Type {
let path = item.canonical_path(ctx);
aster::AstBuilder::new().ty().path().ids(path).build()
}
+ TypeKind::TemplateAlias(inner, ref template_args) |
TypeKind::TemplateRef(inner, ref template_args) => {
// PS: Sorry for the duplication here.
let mut inner_ty = inner.to_rust_ty(ctx).unwrap();
@@ -1618,6 +1625,7 @@ impl TypeCollector for Type {
TypeKind::Pointer(inner) |
TypeKind::Reference(inner) |
TypeKind::Array(inner, _) |
+ TypeKind::TemplateAlias(inner, _) |
TypeKind::Alias(_, inner) |
TypeKind::Named(_, Some(inner)) |
TypeKind::ResolvedTypeRef(inner)
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 56ddf639..0c1de20a 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -206,6 +206,7 @@ impl Item {
}
// XXX Is this completely correct? Partial template specialization
// is hard anyways, sigh...
+ TypeKind::TemplateAlias(_, ref args) |
TypeKind::TemplateRef(_, ref args) => {
args.clone()
}
@@ -277,11 +278,20 @@ impl Item {
TypeKind::Named(ref name, _) => {
return name.to_owned();
}
- _ => {}
- }
-
- ty.name().map(ToOwned::to_owned)
- .unwrap_or_else(|| format!("_bindgen_ty{}", self.id()))
+ // We really codegen and use the inner type, so use an empty
+ // base name so codegen doesn't get confused.
+ //
+ // We should never have this in another kind of type, so...
+ TypeKind::TemplateAlias(..) => {
+ Some("")
+ }
+ // Else use the proper name, or fallback to a name with an
+ // id.
+ _ => {
+ ty.name()
+ }
+ }.map(ToOwned::to_owned)
+ .unwrap_or_else(|| format!("_bindgen_ty{}", self.id()))
}
ItemKind::Function(ref fun) => {
let mut base = fun.name().to_owned();
@@ -329,7 +339,12 @@ impl Item {
// TODO: allow modification of the mangling functions, maybe even per
// item type?
- format!("{}_{}", parent.canonical_name(ctx), base_name)
+ let parent = parent.canonical_name(ctx);
+ if parent.is_empty() {
+ base_name.to_owned()
+ } else {
+ format!("{}_{}", parent, base_name)
+ }
}
pub fn as_module_mut(&mut self) -> Option<&mut Module> {
@@ -444,7 +459,7 @@ impl ClangItemParser for Item {
if cursor.kind() == clangll::CXCursor_UnexposedDecl {
Err(ParseError::Recurse)
} else {
- error!("Unhandled cursor kind: {}", ::clang::kind_to_str(cursor.kind()));
+ error!("Unhandled cursor kind: {} ({})", ::clang::kind_to_str(cursor.kind()), cursor.kind());
Err(ParseError::Continue)
}
}
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index bae2fd88..769b7650 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -146,13 +146,14 @@ impl Type {
type_resolver.resolve_type(t).can_derive_debug(type_resolver)
}
TypeKind::ResolvedTypeRef(t) |
+ TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(_, t) => {
type_resolver.resolve_type(t).can_derive_debug(type_resolver)
}
TypeKind::Comp(ref info) => {
info.can_derive_debug(type_resolver, self.layout(type_resolver))
}
- _ => true,
+ _ => true,
}
}
@@ -177,6 +178,7 @@ impl Type {
pub fn can_derive_copy_in_array(&self, type_resolver: &BindgenContext, item: &Item) -> bool {
match self.kind {
TypeKind::ResolvedTypeRef(t) |
+ TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(_, t) |
TypeKind::Array(t, _) => {
type_resolver.resolve_item(t)
@@ -194,6 +196,7 @@ impl Type {
type_resolver.resolve_item(t).can_derive_copy_in_array(type_resolver)
}
TypeKind::ResolvedTypeRef(t) |
+ TypeKind::TemplateAlias(t, _) |
TypeKind::TemplateRef(t, _) |
TypeKind::Alias(_, t) => {
type_resolver.resolve_item(t).can_derive_copy(type_resolver)
@@ -209,6 +212,7 @@ impl Type {
// FIXME: Can we do something about template parameters? Huh...
match self.kind {
TypeKind::TemplateRef(t, _) |
+ TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(_, t) |
TypeKind::ResolvedTypeRef(t) |
TypeKind::Array(t, _) => {
@@ -225,6 +229,7 @@ impl Type {
pub fn has_destructor(&self, type_resolver: &BindgenContext) -> bool {
self.is_opaque(type_resolver) || match self.kind {
TypeKind::TemplateRef(t, _) |
+ TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(_, t) |
TypeKind::ResolvedTypeRef(t) |
TypeKind::Array(t, _) => {
@@ -263,7 +268,8 @@ impl Type {
type_resolver.resolve_type(sig.return_type())
.signature_contains_named_type(type_resolver, ty)
},
- TypeKind::TemplateRef(_inner, ref template_args) => {
+ TypeKind::TemplateAlias(_, ref template_args) |
+ TypeKind::TemplateRef(_, ref template_args) => {
template_args.iter().any(|arg| {
type_resolver.resolve_type(*arg)
.signature_contains_named_type(type_resolver, ty)
@@ -292,6 +298,7 @@ impl Type {
TypeKind::ResolvedTypeRef(inner) |
TypeKind::Alias(_, inner) |
+ TypeKind::TemplateAlias(inner, _) |
TypeKind::TemplateRef(inner, _)
=> type_resolver.resolve_type(inner).canonical_type(type_resolver),
@@ -327,6 +334,9 @@ pub enum TypeKind {
Float(FloatKind),
/// A type alias, with a name, that points to another type.
Alias(String, ItemId),
+ /// A templated alias, pointing to an inner Alias type, with template
+ /// parameters.
+ TemplateAlias(ItemId, Vec<ItemId>),
/// An array of a type and a lenght.
Array(ItemId, usize),
/// A function type, with a given signature.
@@ -371,6 +381,7 @@ impl Type {
}
TypeKind::ResolvedTypeRef(inner) |
TypeKind::Alias(_, inner) |
+ TypeKind::TemplateAlias(inner, _) |
TypeKind::TemplateRef(inner, _)
=> type_resolver.resolve_type(inner).is_unsized(type_resolver),
TypeKind::Named(..) |
@@ -444,6 +455,51 @@ impl Type {
.expect("C'mon");
TypeKind::Comp(complex)
}
+ CXCursor_TypeAliasTemplateDecl => {
+ debug!("TypeAliasTemplateDecl");
+
+ // We need to manually unwind this one.
+ let mut inner = Err(ParseError::Continue);
+ let mut args = vec![];
+
+ location.visit(|cur, _| {
+ match cur.kind() {
+ CXCursor_TypeAliasDecl => {
+ debug_assert!(cur.cur_type().kind() == CXType_Typedef);
+ inner = Item::from_ty(&cur.cur_type(),
+ Some(*cur),
+ Some(potential_id),
+ ctx);
+ }
+ CXCursor_TemplateTypeParameter => {
+ let default_type =
+ Item::from_ty(&cur.cur_type(),
+ Some(*cur),
+ Some(potential_id),
+ ctx).ok();
+ let param =
+ Item::named_type(cur.spelling(),
+ default_type,
+ potential_id, ctx);
+ args.push(param);
+ }
+ _ => {}
+ }
+ CXChildVisit_Continue
+ });
+
+ if inner.is_err() {
+ error!("Failed to parse templated type alias {:?}", location);
+ return Err(ParseError::Continue);
+ }
+
+ if args.is_empty() {
+ error!("Failed to get any template parameter, maybe a specialization? {:?}", location);
+ return Err(ParseError::Continue);
+ }
+
+ TypeKind::TemplateAlias(inner.unwrap(), args)
+ }
CXCursor_TemplateRef => {
let referenced = location.referenced();
return Self::from_clang_ty(potential_id,
@@ -521,7 +577,7 @@ impl Type {
let signature = try!(FunctionSig::from_ty(ty, &location.unwrap_or(cursor), ctx));
TypeKind::Function(signature)
}
- CXType_Typedef => {
+ CXType_Typedef => {
let inner = cursor.typedef_type();
let inner =
Item::from_ty_or_ref(inner, location, parent_id, ctx);