diff options
author | Nick Fitzgerald <fitzgen@gmail.com> | 2017-03-10 10:46:50 -0800 |
---|---|---|
committer | Nick Fitzgerald <fitzgen@gmail.com> | 2017-03-10 13:53:17 -0800 |
commit | 414442638a913bf5d924f9b16b2ae417cde5840b (patch) | |
tree | 1077c528aaaea889a6a038fe50ab063c5f5bb041 /src | |
parent | 1320efeb79d373acb8dd92fb2722732c251497d8 (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.rs | 8 | ||||
-rw-r--r-- | src/ir/item.rs | 16 | ||||
-rw-r--r-- | src/ir/ty.rs | 14 |
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, |