Skip to content

Commit d01e10e

Browse files
committed
ir: Handle properly template instantiation specializations 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 17d00de commit d01e10e

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
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
@@ -251,25 +251,30 @@ impl TemplateInstantiation {
251251
}
252252
});
253253

254-
let definition = ty.declaration()
255-
.specialized()
256-
.or_else(|| {
257-
let mut template_ref = None;
258-
ty.declaration().visit(|child| {
259-
if child.kind() == CXCursor_TemplateRef {
260-
template_ref = Some(child);
261-
return CXVisit_Break;
262-
}
254+
let declaration = ty.declaration();
255+
let definition = if declaration.kind() == CXCursor_TypeAliasTemplateDecl {
256+
Some(declaration)
257+
} else {
258+
declaration
259+
.specialized()
260+
.or_else(|| {
261+
let mut template_ref = None;
262+
ty.declaration().visit(|child| {
263+
if child.kind() == CXCursor_TemplateRef {
264+
template_ref = Some(child);
265+
return CXVisit_Break;
266+
}
263267

264-
// Instantiations of template aliases might have the
265-
// TemplateRef to the template alias definition arbitrarily
266-
// deep, so we need to recurse here and not only visit
267-
// direct children.
268-
CXChildVisit_Recurse
269-
});
268+
// Instantiations of template aliases might have the
269+
// TemplateRef to the template alias definition arbitrarily
270+
// deep, so we need to recurse here and not only visit
271+
// direct children.
272+
CXChildVisit_Recurse
273+
});
270274

271-
template_ref.and_then(|cur| cur.referenced())
272-
});
275+
template_ref.and_then(|cur| cur.referenced())
276+
})
277+
};
273278

274279
let definition = match definition {
275280
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 {

0 commit comments

Comments
 (0)