Skip to content

Commit dd1dc9e

Browse files
author
bors-servo
authored
Auto merge of #544 - fitzgen:cleanups-without-anon-types, r=emilio
All the template parameters!! The major changes in this PR are: * De-duplication of named template type parameters (this is probably the biggest part of the PR, and nastiest because it is the part that deals with libclang) * Removing the `signature_contains_named_type` stuff, and enabling the more sound template type parameter usage analysis that has been landing in bits here and there. * **LOTS** of new tests for template type parameter usage @emilio: can you also test this on the stylo bindings? I tested on the SpiderMonkey bindings and found a bug and fixed a bug related to instantiations of partially specialized templates. I'd like to make sure that there aren't any latent bugs uncovered in Stylo. This is NOT ready to merge quite yet, but is ready for some more eyeballs that are not mine. Still TODO: * [x] Rebase so that these changes will merge cleanly -- I'll get on this ASAP * [x] Time SpiderMonkey bindings generation with and without these changes to see what the overhead of the new analysis is (if any!) on Large and Real World bindings * [x] Test theses changes on Stylo (thanks @emilio!) * [ ] (optional) and time Stylo bindings generation with and without these changes as well (only if you want to, @emilio) Thanks!
2 parents c85fa24 + 1c4332a commit dd1dc9e

File tree

98 files changed

+2436
-1619
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+2436
-1619
lines changed

src/clang.rs

+39-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use cexpr;
88
use clang_sys::*;
9+
use regex;
910
use std::{mem, ptr, slice};
1011
use std::ffi::{CStr, CString};
1112
use std::fmt;
@@ -126,11 +127,11 @@ impl Cursor {
126127
}
127128

128129
/// Return the number of template arguments used by this cursor's referent,
129-
/// if the referent is either a template specialization or declaration.
130-
/// Returns `None` otherwise.
130+
/// if the referent is either a template instantiation. Returns `None`
131+
/// otherwise.
131132
///
132-
/// NOTE: This may not return `Some` for some non-fully specialized
133-
/// templates, see #193 and #194.
133+
/// NOTE: This may not return `Some` for partial template specializations,
134+
/// see #193 and #194.
134135
pub fn num_template_args(&self) -> Option<u32> {
135136
// XXX: `clang_Type_getNumTemplateArguments` is sort of reliable, while
136137
// `clang_Cursor_getNumTemplateArguments` is totally unreliable.
@@ -302,7 +303,11 @@ impl Cursor {
302303
x: clang_getCursorDefinition(self.x),
303304
};
304305

305-
if ret.is_valid() { Some(ret) } else { None }
306+
if ret.is_valid() && ret.kind() != CXCursor_NoDeclFound {
307+
Some(ret)
308+
} else {
309+
None
310+
}
306311
}
307312
}
308313

@@ -331,8 +336,9 @@ impl Cursor {
331336
}
332337
}
333338

334-
/// Given that this cursor points to a template specialization, get a cursor
335-
/// pointing to the template definition that is being specialized.
339+
/// Given that this cursor points to either a template specialization or a
340+
/// template instantiation, get a cursor pointing to the template definition
341+
/// that is being specialized.
336342
pub fn specialized(&self) -> Option<Cursor> {
337343
unsafe {
338344
let ret = Cursor {
@@ -895,8 +901,8 @@ impl Type {
895901
self.is_valid() && self.kind() != CXType_Unexposed
896902
}
897903

898-
/// Is this type a fully specialized template?
899-
pub fn is_fully_specialized_template(&self) -> bool {
904+
/// Is this type a fully instantiated template?
905+
pub fn is_fully_instantiated_template(&self) -> bool {
900906
// Yep, the spelling of this containing type-parameter is extremely
901907
// nasty... But can happen in <type_traits>. Unfortunately I couldn't
902908
// reduce it enough :(
@@ -908,6 +914,30 @@ impl Type {
908914
_ => true,
909915
}
910916
}
917+
918+
/// Is this type an associated template type? Eg `T::Associated` in
919+
/// this example:
920+
///
921+
/// ```c++
922+
/// template <typename T>
923+
/// class Foo {
924+
/// typename T::Associated member;
925+
/// };
926+
/// ```
927+
pub fn is_associated_type(&self) -> bool {
928+
// This is terrible :(
929+
fn hacky_parse_associated_type<S: AsRef<str>>(spelling: S) -> bool {
930+
lazy_static! {
931+
static ref ASSOC_TYPE_RE: regex::Regex =
932+
regex::Regex::new(r"typename type\-parameter\-\d+\-\d+::.+").unwrap();
933+
}
934+
ASSOC_TYPE_RE.is_match(spelling.as_ref())
935+
}
936+
937+
self.kind() == CXType_Unexposed &&
938+
(hacky_parse_associated_type(self.spelling()) ||
939+
hacky_parse_associated_type(self.canonical_type().spelling()))
940+
}
911941
}
912942

913943
/// The `CanonicalTypeDeclaration` type exists as proof-by-construction that its

0 commit comments

Comments
 (0)