Skip to content

Commit f31a88c

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 f31a88c

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
@@ -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 {

0 commit comments

Comments
 (0)