summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2017-03-10 10:46:50 -0800
committerNick Fitzgerald <fitzgen@gmail.com>2017-03-10 13:53:17 -0800
commit414442638a913bf5d924f9b16b2ae417cde5840b (patch)
tree1077c528aaaea889a6a038fe50ab063c5f5bb041 /src
parent1320efeb79d373acb8dd92fb2722732c251497d8 (diff)
Allow anonymous template types
We have various assertions that the only way that some template parameter related methods will return `None` is if the template definition is marked opaque. These assertions fail in the presence of test cases with unnamed template types, because we never save an IR item for the template type, and subsequently think that the template definition has no template parameters. The assertions are in fact sound and correct, so it doesn't make sense to remove them. Instead it is more correct to save IR items for the anonymous template types and simply let the template usage analysis prevent them from getting codegen'd. Fixes #574
Diffstat (limited to 'src')
-rw-r--r--src/ir/comp.rs8
-rw-r--r--src/ir/item.rs16
-rw-r--r--src/ir/ty.rs14
3 files changed, 20 insertions, 18 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 814204c2..9a6548a7 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -597,14 +597,6 @@ impl CompInfo {
ci.packed = true;
}
CXCursor_TemplateTypeParameter => {
- // Yes! You can arrive here with an empty template parameter
- // name! Awesome, isn't it?
- //
- // see tests/headers/empty_template_param_name.hpp
- if cur.spelling().is_empty() {
- return CXChildVisit_Continue;
- }
-
let param = Item::named_type(None, cur, ctx)
.expect("Item::named_type should't fail when pointing \
at a TemplateTypeParameter");
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 93df9c77..89422e87 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -19,6 +19,7 @@ use std::collections::BTreeSet;
use std::fmt::Write;
use std::io;
use std::iter;
+use regex;
/// A trait to get the canonical name from an item.
///
@@ -1313,8 +1314,19 @@ impl ClangItemParser for Item {
fn is_template_with_spelling(refd: &clang::Cursor,
spelling: &str)
-> bool {
- refd.kind() == clang_sys::CXCursor_TemplateTypeParameter &&
- refd.spelling() == spelling
+ lazy_static! {
+ static ref ANON_TYPE_PARAM_RE: regex::Regex =
+ regex::Regex::new(r"^type\-parameter\-\d+\-\d+$").unwrap();
+ }
+
+ if refd.kind() != clang_sys::CXCursor_TemplateTypeParameter {
+ return false;
+ }
+
+ let refd_spelling = refd.spelling();
+ refd_spelling == spelling ||
+ // Allow for anonymous template parameters.
+ (refd_spelling.is_empty() && ANON_TYPE_PARAM_RE.is_match(spelling.as_ref()))
}
let definition = if is_template_with_spelling(&location,
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 6c8e7363..54925696 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -292,8 +292,12 @@ impl Type {
/// Creates a new named type, with name `name`.
pub fn named(name: String) -> Self {
- assert!(!name.is_empty());
- Self::new(Some(name), None, TypeKind::Named, false)
+ let name = if name.is_empty() {
+ None
+ } else {
+ Some(name)
+ };
+ Self::new(name, None, TypeKind::Named, false)
}
/// Is this a floating point type?
@@ -1127,12 +1131,6 @@ impl Type {
ctx);
}
CXCursor_TemplateTypeParameter => {
- // See the comment in src/ir/comp.rs
- // about the same situation.
- if cur.spelling().is_empty() {
- return CXChildVisit_Continue;
- }
-
let param =
Item::named_type(None,
cur,