From b2e5613d1270fd2ccca319fd862f382c5d81072c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 10 May 2017 14:47:23 +0200 Subject: [PATCH] ir: Handle properly template alias instantiations in clang >3.9. This fixes tests/expectations/tests/type_alias_template_specialized.rs in those clang versions (without regressions, hopefully), and makes the behavior the proper one, without needing replacements. --- src/ir/context.rs | 4 ++- src/ir/template.rs | 39 ++++++++++++++++------------ src/ir/ty.rs | 8 ++++++ tests/expectations/tests/template.rs | 15 +++++++++-- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index 3d3e9fcdb4..95a026da1d 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -299,6 +299,8 @@ impl<'ctx> BindgenContext<'ctx> { let id = item.id(); let is_type = item.kind().is_type(); let is_unnamed = is_type && item.expect_type().name().is_none(); + let is_template_instantiation = + is_type && item.expect_type().is_template_instantiation(); // Be sure to track all the generated children under namespace, even // those generated after resolving typerefs, etc. @@ -317,7 +319,7 @@ impl<'ctx> BindgenContext<'ctx> { // Unnamed items can have an USR, but they can't be referenced from // other sites explicitly and the USR can match if the unnamed items are // nested, so don't bother tracking them. - if is_type && declaration.is_some() { + if is_type && !is_template_instantiation && declaration.is_some() { let mut declaration = declaration.unwrap(); if !declaration.is_valid() { if let Some(location) = location { diff --git a/src/ir/template.rs b/src/ir/template.rs index 5861929fff..b1ccbd6fa0 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -240,25 +240,30 @@ impl TemplateInstantiation { .collect() }); - let definition = ty.declaration() - .specialized() - .or_else(|| { - let mut template_ref = None; - ty.declaration().visit(|child| { - if child.kind() == CXCursor_TemplateRef { - template_ref = Some(child); - return CXVisit_Break; - } + let declaration = ty.declaration(); + let definition = if declaration.kind() == CXCursor_TypeAliasTemplateDecl { + Some(declaration) + } else { + declaration + .specialized() + .or_else(|| { + let mut template_ref = None; + ty.declaration().visit(|child| { + if child.kind() == CXCursor_TemplateRef { + template_ref = Some(child); + return CXVisit_Break; + } - // Instantiations of template aliases might have the - // TemplateRef to the template alias definition arbitrarily - // deep, so we need to recurse here and not only visit - // direct children. - CXChildVisit_Recurse - }); + // Instantiations of template aliases might have the + // TemplateRef to the template alias definition arbitrarily + // deep, so we need to recurse here and not only visit + // direct children. + CXChildVisit_Recurse + }); - template_ref.and_then(|cur| cur.referenced()) - }); + template_ref.and_then(|cur| cur.referenced()) + }) + }; let definition = match definition { Some(def) => def, diff --git a/src/ir/ty.rs b/src/ir/ty.rs index a9054e981c..3bb1965b3c 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -109,6 +109,14 @@ impl Type { } } + /// Is this a template instantiation type? + pub fn is_template_instantiation(&self) -> bool { + match self.kind { + TypeKind::TemplateInstantiation(..) => true, + _ => false, + } + } + /// Is this a template alias type? pub fn is_template_alias(&self) -> bool { match self.kind { diff --git a/tests/expectations/tests/template.rs b/tests/expectations/tests/template.rs index d4f81711b6..00061ecd87 100644 --- a/tests/expectations/tests/template.rs +++ b/tests/expectations/tests/template.rs @@ -256,7 +256,18 @@ fn __bindgen_test_layout_Foo_instantiation_95() { Foo<::std::os::raw::c_int> ) )); } #[test] -fn __bindgen_test_layout_Rooted_instantiation_106() { +fn __bindgen_test_layout_Foo_instantiation_101() { + assert_eq!(::std::mem::size_of::>() , 24usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + Foo<::std::os::raw::c_int> ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + Foo<::std::os::raw::c_int> ) )); +} +#[test] +fn __bindgen_test_layout_Rooted_instantiation_111() { assert_eq!(::std::mem::size_of::>() , 24usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -267,7 +278,7 @@ fn __bindgen_test_layout_Rooted_instantiation_106() { Rooted<*mut ::std::os::raw::c_void> ) )); } #[test] -fn __bindgen_test_layout_WithDtor_instantiation_114() { +fn __bindgen_test_layout_WithDtor_instantiation_123() { assert_eq!(::std::mem::size_of::>() , 4usize , concat ! ( "Size of template specialization: " , stringify ! (