diff options
author | Nick Fitzgerald <fitzgen@gmail.com> | 2017-02-07 14:33:57 -0800 |
---|---|---|
committer | Nick Fitzgerald <fitzgen@gmail.com> | 2017-02-08 10:04:08 -0800 |
commit | 775c15c3dcfa488c0ca4236805606f345fbbc2e2 (patch) | |
tree | 8ee4421cfbad6a1192d7031d3628b75f1dbf1842 | |
parent | 910b0d6458f51e553b0e229af41fa313b3d3f10c (diff) |
Introduce a CanonicalDeclaration type
The `CanonicalTypeDeclaration` type exists as proof-by-construction that its
cursor is the canonical declaration for its type. If you have a
`CanonicalTypeDeclaration` instance, you know for sure that the type and cursor
match up in a canonical declaration relationship, and it simply cannot be
otherwise.
-rw-r--r-- | src/clang.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/clang.rs b/src/clang.rs index b35d2187..6474db2c 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -684,6 +684,31 @@ impl Type { } } + /// Get the canonical declaration of this type, if it is available. + pub fn canonical_declaration(&self, + location: Option<&Cursor>) + -> Option<CanonicalTypeDeclaration> { + let mut declaration = self.declaration(); + if !declaration.is_valid() { + if let Some(location) = location { + let mut location = *location; + if let Some(referenced) = location.referenced() { + location = referenced; + } + if location.is_template_like() { + declaration = location; + } + } + } + + let canonical = declaration.canonical(); + if canonical.is_valid() && canonical.kind() != CXCursor_NoDeclFound { + Some(CanonicalTypeDeclaration(*self, canonical)) + } else { + None + } + } + /// Get a raw display name for this type. pub fn spelling(&self) -> String { unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) } @@ -874,6 +899,26 @@ impl Type { } } +/// The `CanonicalTypeDeclaration` type exists as proof-by-construction that its +/// cursor is the canonical declaration for its type. If you have a +/// `CanonicalTypeDeclaration` instance, you know for sure that the type and +/// cursor match up in a canonical declaration relationship, and it simply +/// cannot be otherwise. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct CanonicalTypeDeclaration(Type, Cursor); + +impl CanonicalTypeDeclaration { + /// Get the type. + pub fn ty(&self) -> &Type { + &self.0 + } + + /// Get the type's canonical declaration cursor. + pub fn cursor(&self) -> &Cursor { + &self.1 + } +} + /// An iterator for a type's template arguments. pub struct TypeTemplateArgIterator { x: CXType, |