Skip to content

Commit bd6fe14

Browse files
committed
objc: Trace conforming protocols
Keeps note of the ItemIds that the Objective C interface conforms to, and when tracing, visits also them.
1 parent 4067214 commit bd6fe14

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

src/ir/objc.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
//! Objective C types
22
3-
use super::context::BindgenContext;
3+
use super::context::{BindgenContext, ItemId};
44
use super::function::FunctionSig;
55
use super::traversal::{Trace, Tracer};
6+
use super::ty::TypeKind;
67
use clang;
78
use clang_sys::CXChildVisit_Continue;
89
use clang_sys::CXCursor_ObjCCategoryDecl;
910
use clang_sys::CXCursor_ObjCClassRef;
1011
use clang_sys::CXCursor_ObjCInstanceMethodDecl;
1112
use clang_sys::CXCursor_ObjCProtocolDecl;
13+
use clang_sys::CXCursor_ObjCProtocolRef;
1214

1315
/// Objective C interface as used in TypeKind
1416
///
@@ -23,6 +25,8 @@ pub struct ObjCInterface {
2325

2426
is_protocol: bool,
2527

28+
conforms_to: Vec<ItemId>,
29+
2630
/// List of the methods defined in this interfae
2731
methods: Vec<ObjCInstanceMethod>,
2832
}
@@ -47,6 +51,7 @@ impl ObjCInterface {
4751
name: name.to_owned(),
4852
category: None,
4953
is_protocol: false,
54+
conforms_to: Vec::new(),
5055
methods: Vec::new(),
5156
}
5257
}
@@ -98,6 +103,34 @@ impl ObjCInterface {
98103
interface.category = Some(cursor.spelling());
99104
}
100105
}
106+
CXCursor_ObjCProtocolRef => {
107+
// Gather protocols this interface conforms to
108+
let needle = format!("protocol_{}", c.spelling());
109+
let items_map = ctx.items();
110+
debug!("Interface {} conforms to {}, find the item", interface.name, needle);
111+
112+
for (id, item) in items_map
113+
{
114+
if let Some(ty) = item.as_type() {
115+
match *ty.kind() {
116+
TypeKind::ObjCInterface(ref protocol) => {
117+
if protocol.is_protocol
118+
{
119+
debug!("Checking protocol {}, ty.name {:?}", protocol.name, ty.name());
120+
if Some(needle.as_ref()) == ty.name()
121+
{
122+
debug!("Found conforming protocol {:?}", item);
123+
interface.conforms_to.push(*id);
124+
break;
125+
}
126+
}
127+
}
128+
_ => {}
129+
}
130+
}
131+
}
132+
133+
}
101134
CXCursor_ObjCInstanceMethodDecl => {
102135
let name = c.spelling();
103136
let signature =
@@ -176,9 +209,12 @@ impl Trace for ObjCInterface {
176209
fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, _: &())
177210
where T: Tracer,
178211
{
179-
for method in &self.methods
180-
{
212+
for method in &self.methods {
181213
method.signature.trace(context, tracer, &());
182214
}
215+
216+
for protocol in &self.conforms_to {
217+
tracer.visit(*protocol);
218+
}
183219
}
184220
}

0 commit comments

Comments
 (0)