diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-05-10 14:47:23 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-05-10 15:45:28 +0200 |
commit | b2e5613d1270fd2ccca319fd862f382c5d81072c (patch) | |
tree | 1191183ade3d3b183f0ea5999831778615704c44 /src | |
parent | 31e440917cdc8ac57cd69ddf929e90a7c4b46367 (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.rs | 4 | ||||
-rw-r--r-- | src/ir/template.rs | 39 | ||||
-rw-r--r-- | src/ir/ty.rs | 8 |
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 { |