Feed enum field offsets to type vistors.
This commit is contained in:
parent
44d4d6de76
commit
0ca1885da1
5 changed files with 61 additions and 20 deletions
|
|
@ -406,7 +406,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
disr_val: int,
|
||||
n_fields: uint,
|
||||
name: &str) -> bool {
|
||||
self.inner.push_ptr();
|
||||
self.inner.push_ptr(); // NOTE remove after next snapshot
|
||||
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
|
||||
n_fields, name) {
|
||||
return false;
|
||||
|
|
@ -414,6 +414,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
true
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
|
||||
unsafe { self.align((*inner).align); }
|
||||
if ! self.inner.visit_enum_variant_field(i, inner) { return false; }
|
||||
|
|
@ -421,6 +422,15 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
true
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool {
|
||||
self.inner.push_ptr();
|
||||
self.bump(offset);
|
||||
if ! self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
|
||||
self.inner.pop_ptr();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_enum_variant(&self, variant: uint,
|
||||
disr_val: int,
|
||||
n_fields: uint,
|
||||
|
|
@ -429,7 +439,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
n_fields, name) {
|
||||
return false;
|
||||
}
|
||||
self.inner.pop_ptr();
|
||||
self.inner.pop_ptr(); // NOTE remove after next snapshot
|
||||
true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,6 +193,14 @@ pub impl ReprVisitor {
|
|||
self.bump(sys::size_of::<T>());
|
||||
}
|
||||
|
||||
#[cfg(stage0)] #[inline(always)]
|
||||
fn stage0_bump_past<T>(&self) {
|
||||
self.bump_past::<T>();
|
||||
}
|
||||
#[cfg(not(stage0))] #[inline(always)]
|
||||
fn stage0_bump_past<T>(&self) {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_inner(&self, inner: *TyDesc) -> bool {
|
||||
self.visit_ptr_inner(self.ptr, inner)
|
||||
|
|
@ -487,7 +495,7 @@ impl TyVisitor for ReprVisitor {
|
|||
self.var_stk.push(TagMismatch);
|
||||
}
|
||||
};
|
||||
self.bump_past::<int>();
|
||||
self.stage0_bump_past::<int>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -500,6 +508,7 @@ impl TyVisitor for ReprVisitor {
|
|||
true
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
|
||||
match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
|
||||
Degenerate | TagMatch => {
|
||||
|
|
@ -515,6 +524,22 @@ impl TyVisitor for ReprVisitor {
|
|||
true
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
fn visit_enum_variant_field(&self, i: uint, _offset: uint, inner: *TyDesc) -> bool {
|
||||
match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
|
||||
Degenerate | TagMatch => {
|
||||
if i != 0 {
|
||||
self.writer.write_str(", ");
|
||||
}
|
||||
if ! self.visit_inner(inner) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
TagMismatch => ()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_enum_variant(&self, _variant: uint,
|
||||
_disr_val: int,
|
||||
n_fields: uint,
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ pub mod intrinsic {
|
|||
disr_val: int,
|
||||
n_fields: uint,
|
||||
name: &str) -> bool;
|
||||
fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_leave_enum_variant(&self, variant: uint,
|
||||
disr_val: int,
|
||||
n_fields: uint,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
|
||||
use lib::llvm::{TypeRef, ValueRef};
|
||||
use middle::trans::adt;
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::build::*;
|
||||
use middle::trans::callee::{ArgVals, DontAutorefArg};
|
||||
|
|
@ -266,23 +267,28 @@ pub impl Reflector {
|
|||
// variant?
|
||||
ty::ty_enum(did, ref substs) => {
|
||||
let bcx = self.bcx;
|
||||
let tcx = bcx.ccx().tcx;
|
||||
let variants = ty::substd_enum_variants(tcx, did, substs);
|
||||
let ccx = bcx.ccx();
|
||||
let repr = adt::represent_type(bcx.ccx(), t);
|
||||
let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
|
||||
|
||||
let extra = ~[self.c_uint(vec::len(variants))]
|
||||
let enum_args = ~[self.c_uint(vec::len(variants))]
|
||||
+ self.c_size_and_align(t);
|
||||
do self.bracketed(~"enum", extra) |this| {
|
||||
do self.bracketed(~"enum", enum_args) |this| {
|
||||
for variants.eachi |i, v| {
|
||||
let extra1 = ~[this.c_uint(i),
|
||||
this.c_int(v.disr_val),
|
||||
this.c_uint(vec::len(v.args)),
|
||||
this.c_slice(
|
||||
bcx.ccx().sess.str_of(v.name))];
|
||||
do this.bracketed(~"enum_variant", extra1) |this| {
|
||||
let variant_args = ~[this.c_uint(i),
|
||||
this.c_int(v.disr_val),
|
||||
this.c_uint(vec::len(v.args)),
|
||||
this.c_slice(ccx.sess.str_of(v.name))];
|
||||
do this.bracketed(~"enum_variant", variant_args) |this| {
|
||||
for v.args.eachi |j, a| {
|
||||
let extra = ~[this.c_uint(j),
|
||||
this.c_tydesc(*a)];
|
||||
this.visit(~"enum_variant_field", extra);
|
||||
let bcx = this.bcx;
|
||||
let null = C_null(T_ptr(type_of(ccx, t)));
|
||||
let offset = p2i(ccx, adt::trans_field_ptr(bcx, repr, null,
|
||||
v.disr_val, j));
|
||||
let field_args = ~[this.c_uint(j),
|
||||
offset,
|
||||
this.c_tydesc(*a)];
|
||||
this.visit(~"enum_variant_field", field_args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -394,8 +394,8 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
|
|||
true
|
||||
}
|
||||
|
||||
fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
|
||||
if ! self.inner.visit_enum_variant_field(i, inner) { return false; }
|
||||
fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool {
|
||||
if ! self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -594,7 +594,7 @@ impl TyVisitor for my_visitor {
|
|||
_disr_val: int,
|
||||
_n_fields: uint,
|
||||
_name: &str) -> bool { true }
|
||||
fn visit_enum_variant_field(&self, _i: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_enum_variant_field(&self, _i: uint, _offset: uint, inner: *TyDesc) -> bool {
|
||||
self.visit_inner(inner)
|
||||
}
|
||||
fn visit_leave_enum_variant(&self, _variant: uint,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue