Skip to content

Commit d182c14

Browse files
committed
Visit the substructure for classes and enums as well.
1 parent b8af02e commit d182c14

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

src/rustc/front/intrinsic.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,29 @@ mod intrinsic {
6262
/*, name: str/& */) -> bool;
6363
fn visit_leave_rec(n_fields: uint) -> bool;
6464

65+
fn visit_enter_class(n_fields: uint) -> bool;
66+
fn visit_enter_class_field(mtbl: uint, i: uint
67+
/*, name: str/& */) -> bool;
68+
fn visit_leave_class_field(mtbl: uint, i: uint
69+
/*, name: str/& */) -> bool;
70+
fn visit_leave_class(n_fields: uint) -> bool;
71+
6572
fn visit_enter_tup(n_fields: uint) -> bool;
6673
fn visit_enter_tup_field(i: uint) -> bool;
6774
fn visit_leave_tup_field(i: uint) -> bool;
6875
fn visit_leave_tup(n_fields: uint) -> bool;
6976

77+
fn visit_enter_enum(n_variants: uint) -> bool;
78+
fn visit_enter_enum_variant(variant: uint,
79+
disr_val: int,
80+
n_fields: uint) -> bool;
81+
fn visit_enter_enum_variant_field(i: uint) -> bool;
82+
fn visit_leave_enum_variant_field(i: uint) -> bool;
83+
fn visit_leave_enum_variant(variant: uint,
84+
disr_val: int,
85+
n_fields: uint) -> bool;
86+
fn visit_leave_enum(n_variants: uint) -> bool;
87+
7088
fn visit_enter_fn(purity: uint, proto: uint,
7189
n_inputs: uint, retstyle: uint) -> bool;
7290
fn visit_enter_fn_input(i: uint, mode: uint) -> bool;
@@ -76,9 +94,6 @@ mod intrinsic {
7694
fn visit_leave_fn(purity: uint, proto: uint,
7795
n_inputs: uint, retstyle: uint) -> bool;
7896

79-
fn visit_class() -> bool;
80-
fn visit_enum() -> bool;
81-
8297
fn visit_iface() -> bool;
8398
fn visit_enter_res() -> bool;
8499
fn visit_leave_res() -> bool;

src/rustc/middle/trans/reflect.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ impl methods for reflector {
2222
C_uint(self.bcx.ccx(), u)
2323
}
2424

25+
fn c_int(i: int) -> ValueRef {
26+
C_int(self.bcx.ccx(), i)
27+
}
28+
2529
fn visit(ty_name: str, args: [ValueRef]) {
2630
let tcx = self.bcx.tcx();
2731
let mth_idx = option::get(ty::method_idx("visit_" + ty_name,
@@ -179,9 +183,52 @@ impl methods for reflector {
179183
self.visit("leave_fn", extra);
180184
}
181185

182-
// FIXME: these need substructure-walks
183-
ty::ty_class(_, _) { self.leaf("class") }
184-
ty::ty_enum(_, _) { self.leaf("enum") }
186+
ty::ty_class(did, substs) {
187+
let bcx = self.bcx;
188+
let tcx = bcx.ccx().tcx;
189+
let fields = ty::class_items_as_fields(tcx, did, substs);
190+
self.visit("enter_class", [self.c_uint(vec::len(fields))]);
191+
for fields.eachi {|i, field|
192+
self.bracketed_mt("class_field", field.mt,
193+
[self.c_uint(i)
194+
/*
195+
FIXME: doesn't work presently.
196+
C_estr_slice(self.bcx.ccx(),
197+
field.ident)
198+
*/
199+
]);
200+
}
201+
self.visit("leave_class", [self.c_uint(vec::len(fields))]);
202+
}
203+
204+
// FIXME: visiting all the variants in turn is probably
205+
// not ideal. It'll work but will get costly on big enums.
206+
// Maybe let the visitor tell us if it wants to visit only
207+
// a particular variant?
208+
ty::ty_enum(did, substs) {
209+
let bcx = self.bcx;
210+
let tcx = bcx.ccx().tcx;
211+
let variants = ty::substd_enum_variants(tcx, did, substs);
212+
213+
self.visit("enter_enum", [self.c_uint(vec::len(variants))]);
214+
for variants.eachi {|i, v|
215+
let extra = [self.c_uint(i),
216+
self.c_int(v.disr_val),
217+
self.c_uint(vec::len(v.args))
218+
/*
219+
FIXME: doesn't work presently.
220+
C_estr_slice(self.bcx.ccx(),
221+
v.name)
222+
*/];
223+
self.visit("enter_enum_variant", extra);
224+
for v.args.eachi {|j, a|
225+
self.bracketed_t("enum_variant_field", a,
226+
[self.c_uint(j)]);
227+
}
228+
self.visit("leave_enum_variant", extra);
229+
}
230+
self.visit("leave_enum", [self.c_uint(vec::len(variants))]);
231+
}
185232

186233
// Miscallaneous extra types
187234
ty::ty_iface(_, _) { self.leaf("iface") }

src/test/run-pass/reflect-visit-type.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ impl of intrinsic::ty_visitor for my_visitor {
8787
/*,name: str/&*/) -> bool { true }
8888
fn visit_leave_rec(_n_fields: uint) -> bool { true }
8989

90+
fn visit_enter_class(_n_fields: uint) -> bool { true }
91+
fn visit_enter_class_field(_mtbl: uint, _i: uint
92+
/*,name: str/&*/) -> bool { true }
93+
fn visit_leave_class_field(_mtbl: uint, _i: uint
94+
/*,name: str/&*/) -> bool { true }
95+
fn visit_leave_class(_n_fields: uint) -> bool { true }
96+
9097
fn visit_enter_tup(_n_fields: uint) -> bool { true }
9198
fn visit_enter_tup_field(_i: uint) -> bool { true }
9299
fn visit_leave_tup_field(_i: uint) -> bool { true }
@@ -101,8 +108,16 @@ impl of intrinsic::ty_visitor for my_visitor {
101108
fn visit_leave_fn(_purity: uint, _proto: uint,
102109
_n_inputs: uint, _retstyle: uint) -> bool { true }
103110

104-
fn visit_class() -> bool { true }
105-
fn visit_enum() -> bool { true }
111+
fn visit_enter_enum(_n_variants: uint) -> bool { true }
112+
fn visit_enter_enum_variant(_variant: uint,
113+
_disr_val: int,
114+
_n_fields: uint) -> bool { true }
115+
fn visit_enter_enum_variant_field(_i: uint) -> bool { true }
116+
fn visit_leave_enum_variant_field(_i: uint) -> bool { true }
117+
fn visit_leave_enum_variant(_variant: uint,
118+
_disr_val: int,
119+
_n_fields: uint) -> bool { true }
120+
fn visit_leave_enum(_n_variants: uint) -> bool { true }
106121

107122
fn visit_iface() -> bool { true }
108123
fn visit_enter_res() -> bool { true }

0 commit comments

Comments
 (0)