summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-05-10 14:47:23 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-05-10 15:45:28 +0200
commitb2e5613d1270fd2ccca319fd862f382c5d81072c (patch)
tree1191183ade3d3b183f0ea5999831778615704c44 /src
parent31e440917cdc8ac57cd69ddf929e90a7c4b46367 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/ir/context.rs4
-rw-r--r--src/ir/template.rs39
-rw-r--r--src/ir/ty.rs8
3 files changed, 33 insertions, 18 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 3d3e9fcd..95a026da 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 5861929f..b1ccbd6f 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 a9054e98..3bb1965b 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 {