diff options
author | Mikko Lehtonen <scoopr@iki.fi> | 2017-03-04 02:22:50 +0200 |
---|---|---|
committer | Mikko Lehtonen <scoopr@iki.fi> | 2017-03-04 23:02:38 +0200 |
commit | bd6fe14d6ac958985576798da47aaaab81180392 (patch) | |
tree | 766637874d6e397ba9241ec9975634baf412f017 /src | |
parent | 4067214465da14e4037be47088d5f0c97de1f9e3 (diff) |
objc: Trace conforming protocols
Keeps note of the ItemIds that the Objective C interface conforms to,
and when tracing, visits also them.
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/objc.rs | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/src/ir/objc.rs b/src/ir/objc.rs index 5c721243..485bda8a 100644 --- a/src/ir/objc.rs +++ b/src/ir/objc.rs @@ -1,14 +1,16 @@ //! Objective C types -use super::context::BindgenContext; +use super::context::{BindgenContext, ItemId}; use super::function::FunctionSig; use super::traversal::{Trace, Tracer}; +use super::ty::TypeKind; use clang; use clang_sys::CXChildVisit_Continue; use clang_sys::CXCursor_ObjCCategoryDecl; use clang_sys::CXCursor_ObjCClassRef; use clang_sys::CXCursor_ObjCInstanceMethodDecl; use clang_sys::CXCursor_ObjCProtocolDecl; +use clang_sys::CXCursor_ObjCProtocolRef; /// Objective C interface as used in TypeKind /// @@ -23,6 +25,8 @@ pub struct ObjCInterface { is_protocol: bool, + conforms_to: Vec<ItemId>, + /// List of the methods defined in this interfae methods: Vec<ObjCInstanceMethod>, } @@ -47,6 +51,7 @@ impl ObjCInterface { name: name.to_owned(), category: None, is_protocol: false, + conforms_to: Vec::new(), methods: Vec::new(), } } @@ -98,6 +103,34 @@ impl ObjCInterface { interface.category = Some(cursor.spelling()); } } + CXCursor_ObjCProtocolRef => { + // Gather protocols this interface conforms to + let needle = format!("protocol_{}", c.spelling()); + let items_map = ctx.items(); + debug!("Interface {} conforms to {}, find the item", interface.name, needle); + + for (id, item) in items_map + { + if let Some(ty) = item.as_type() { + match *ty.kind() { + TypeKind::ObjCInterface(ref protocol) => { + if protocol.is_protocol + { + debug!("Checking protocol {}, ty.name {:?}", protocol.name, ty.name()); + if Some(needle.as_ref()) == ty.name() + { + debug!("Found conforming protocol {:?}", item); + interface.conforms_to.push(*id); + break; + } + } + } + _ => {} + } + } + } + + } CXCursor_ObjCInstanceMethodDecl => { let name = c.spelling(); let signature = @@ -176,9 +209,12 @@ impl Trace for ObjCInterface { fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, _: &()) where T: Tracer, { - for method in &self.methods - { + for method in &self.methods { method.signature.trace(context, tracer, &()); } + + for protocol in &self.conforms_to { + tracer.visit(*protocol); + } } } |