Skip to content

Commit b2e5613

Browse files
committed
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.
1 parent 31e4409 commit b2e5613

File tree

4 files changed

+46
-20
lines changed

4 files changed

+46
-20
lines changed

src/ir/context.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ impl<'ctx> BindgenContext<'ctx> {
299299
let id = item.id();
300300
let is_type = item.kind().is_type();
301301
let is_unnamed = is_type && item.expect_type().name().is_none();
302+
let is_template_instantiation =
303+
is_type && item.expect_type().is_template_instantiation();
302304

303305
// Be sure to track all the generated children under namespace, even
304306
// those generated after resolving typerefs, etc.
@@ -317,7 +319,7 @@ impl<'ctx> BindgenContext<'ctx> {
317319
// Unnamed items can have an USR, but they can't be referenced from
318320
// other sites explicitly and the USR can match if the unnamed items are
319321
// nested, so don't bother tracking them.
320-
if is_type && declaration.is_some() {
322+
if is_type && !is_template_instantiation && declaration.is_some() {
321323
let mut declaration = declaration.unwrap();
322324
if !declaration.is_valid() {
323325
if let Some(location) = location {

src/ir/template.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -240,25 +240,30 @@ impl TemplateInstantiation {
240240
.collect()
241241
});
242242

243-
let definition = ty.declaration()
244-
.specialized()
245-
.or_else(|| {
246-
let mut template_ref = None;
247-
ty.declaration().visit(|child| {
248-
if child.kind() == CXCursor_TemplateRef {
249-
template_ref = Some(child);
250-
return CXVisit_Break;
251-
}
243+
let declaration = ty.declaration();
244+
let definition = if declaration.kind() == CXCursor_TypeAliasTemplateDecl {
245+
Some(declaration)
246+
} else {
247+
declaration
248+
.specialized()
249+
.or_else(|| {
250+
let mut template_ref = None;
251+
ty.declaration().visit(|child| {
252+
if child.kind() == CXCursor_TemplateRef {
253+
template_ref = Some(child);
254+
return CXVisit_Break;
255+
}
252256

253-
// Instantiations of template aliases might have the
254-
// TemplateRef to the template alias definition arbitrarily
255-
// deep, so we need to recurse here and not only visit
256-
// direct children.
257-
CXChildVisit_Recurse
258-
});
257+
// Instantiations of template aliases might have the
258+
// TemplateRef to the template alias definition arbitrarily
259+
// deep, so we need to recurse here and not only visit
260+
// direct children.
261+
CXChildVisit_Recurse
262+
});
259263

260-
template_ref.and_then(|cur| cur.referenced())
261-
});
264+
template_ref.and_then(|cur| cur.referenced())
265+
})
266+
};
262267

263268
let definition = match definition {
264269
Some(def) => def,

src/ir/ty.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ impl Type {
109109
}
110110
}
111111

112+
/// Is this a template instantiation type?
113+
pub fn is_template_instantiation(&self) -> bool {
114+
match self.kind {
115+
TypeKind::TemplateInstantiation(..) => true,
116+
_ => false,
117+
}
118+
}
119+
112120
/// Is this a template alias type?
113121
pub fn is_template_alias(&self) -> bool {
114122
match self.kind {

tests/expectations/tests/template.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,18 @@ fn __bindgen_test_layout_Foo_instantiation_95() {
256256
Foo<::std::os::raw::c_int> ) ));
257257
}
258258
#[test]
259-
fn __bindgen_test_layout_Rooted_instantiation_106() {
259+
fn __bindgen_test_layout_Foo_instantiation_101() {
260+
assert_eq!(::std::mem::size_of::<Foo<::std::os::raw::c_int>>() , 24usize ,
261+
concat ! (
262+
"Size of template specialization: " , stringify ! (
263+
Foo<::std::os::raw::c_int> ) ));
264+
assert_eq!(::std::mem::align_of::<Foo<::std::os::raw::c_int>>() , 8usize ,
265+
concat ! (
266+
"Alignment of template specialization: " , stringify ! (
267+
Foo<::std::os::raw::c_int> ) ));
268+
}
269+
#[test]
270+
fn __bindgen_test_layout_Rooted_instantiation_111() {
260271
assert_eq!(::std::mem::size_of::<Rooted<*mut ::std::os::raw::c_void>>() ,
261272
24usize , concat ! (
262273
"Size of template specialization: " , stringify ! (
@@ -267,7 +278,7 @@ fn __bindgen_test_layout_Rooted_instantiation_106() {
267278
Rooted<*mut ::std::os::raw::c_void> ) ));
268279
}
269280
#[test]
270-
fn __bindgen_test_layout_WithDtor_instantiation_114() {
281+
fn __bindgen_test_layout_WithDtor_instantiation_123() {
271282
assert_eq!(::std::mem::size_of::<WithDtor<::std::os::raw::c_int>>() ,
272283
4usize , concat ! (
273284
"Size of template specialization: " , stringify ! (

0 commit comments

Comments
 (0)