提交 78dd95f4 编写于 作者: D Denis Merigoux 提交者: Eduard-Mihai Burtescu

Generalized base::unsize_thin_ptr

上级 034f6975
...@@ -208,7 +208,7 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>( ...@@ -208,7 +208,7 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target)) let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target))
.field(cx, abi::FAT_PTR_EXTRA); .field(cx, abi::FAT_PTR_EXTRA);
cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()), cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()),
cx.backend_type(vtable_ptr)) cx.backend_type(&vtable_ptr))
} }
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}",
source, source,
...@@ -217,12 +217,12 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>( ...@@ -217,12 +217,12 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
} }
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer. /// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
pub fn unsize_thin_ptr( pub fn unsize_thin_ptr<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Builder<'a, 'll, 'tcx>, bx: &Bx,
src: &'ll Value, src: Bx::Value,
src_ty: Ty<'tcx>, src_ty: Ty<'tcx>,
dst_ty: Ty<'tcx> dst_ty: Ty<'tcx>
) -> (&'ll Value, &'ll Value) { ) -> (Bx::Value, Bx::Value) {
debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty); debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty);
match (&src_ty.sty, &dst_ty.sty) { match (&src_ty.sty, &dst_ty.sty) {
(&ty::Ref(_, a, _), (&ty::Ref(_, a, _),
...@@ -232,13 +232,13 @@ pub fn unsize_thin_ptr( ...@@ -232,13 +232,13 @@ pub fn unsize_thin_ptr(
(&ty::RawPtr(ty::TypeAndMut { ty: a, .. }), (&ty::RawPtr(ty::TypeAndMut { ty: a, .. }),
&ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => { &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => {
assert!(bx.cx().type_is_sized(a)); assert!(bx.cx().type_is_sized(a));
let ptr_ty = bx.cx().type_ptr_to(bx.cx().layout_of(b).llvm_type(bx.cx())); let ptr_ty = bx.cx().type_ptr_to(bx.cx().backend_type(&bx.cx().layout_of(b)));
(bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None)) (bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None))
} }
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => { (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty()); let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty());
assert!(bx.cx().type_is_sized(a)); assert!(bx.cx().type_is_sized(a));
let ptr_ty = bx.cx().type_ptr_to(bx.cx().layout_of(b).llvm_type(bx.cx())); let ptr_ty = bx.cx().type_ptr_to(bx.cx().backend_type(&bx.cx().layout_of(b)));
(bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None)) (bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None))
} }
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
...@@ -263,8 +263,8 @@ pub fn unsize_thin_ptr( ...@@ -263,8 +263,8 @@ pub fn unsize_thin_ptr(
} }
let (lldata, llextra) = result.unwrap(); let (lldata, llextra) = result.unwrap();
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
(bx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bx.cx(), 0, true)), (bx.bitcast(lldata, bx.cx().scalar_pair_element_backend_type(&dst_layout, 0, true)),
bx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bx.cx(), 1, true))) bx.bitcast(llextra, bx.cx().scalar_pair_element_backend_type(&dst_layout, 1, true)))
} }
_ => bug!("unsize_thin_ptr: called on bad types"), _ => bug!("unsize_thin_ptr: called on bad types"),
} }
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
use attributes; use attributes;
use common;
use llvm; use llvm;
use rustc::dep_graph::DepGraphSafe; use rustc::dep_graph::DepGraphSafe;
use rustc::hir; use rustc::hir;
...@@ -746,31 +745,6 @@ pub fn eh_unwind_resume(&self) -> &'b Value { ...@@ -746,31 +745,6 @@ pub fn eh_unwind_resume(&self) -> &'b Value {
llfn llfn
} }
pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
common::type_needs_drop(self.tcx, ty)
}
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
common::type_is_sized(self.tcx, ty)
}
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
common::type_is_freeze(self.tcx, ty)
}
pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
use syntax_pos::DUMMY_SP;
if ty.is_sized(self.tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) {
return false;
}
let tail = self.tcx.struct_tail(ty);
match tail.sty {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
}
}
} }
impl ty::layout::HasDataLayout for CodegenCx<'ll, 'tcx> { impl ty::layout::HasDataLayout for CodegenCx<'ll, 'tcx> {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
use rustc::ty::layout::{LayoutOf, HasTyCtxt}; use rustc::ty::layout::{LayoutOf, HasTyCtxt};
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use value::Value; use value::Value;
use interfaces::{BuilderMethods, ConstMethods}; use interfaces::*;
pub fn size_and_align_of_dst( pub fn size_and_align_of_dst(
bx: &Builder<'_, 'll, 'tcx>, bx: &Builder<'_, 'll, 'tcx>,
......
...@@ -61,10 +61,21 @@ pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> { ...@@ -61,10 +61,21 @@ pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> {
fn type_from_integer(&self, i: layout::Integer) -> Self::Type; fn type_from_integer(&self, i: layout::Integer) -> Self::Type;
fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type; fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type; fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool;
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool;
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool;
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool;
} }
pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> { pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
fn backend_type(&self, ty: TyLayout<'tcx>) -> Self::Type; fn backend_type(&self, ty: &TyLayout<'tcx>) -> Self::Type;
fn scalar_pair_element_backend_type<'a>(
&self,
ty: &TyLayout<'tcx>,
index: usize,
immediate: bool
) -> Self::Type;
} }
pub trait TypeMethods<'tcx>: pub trait TypeMethods<'tcx>:
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;
use super::FunctionCx; use super::FunctionCx;
use value::Value; use value::Value;
use interfaces::*;
pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx, &'ll Value>) -> BitSet<mir::Local> { pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx, &'ll Value>) -> BitSet<mir::Local> {
let mir = fx.mir; let mir = fx.mir;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;
use value::Value; use value::Value;
use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, IntrinsicDeclarationMethods}; use interfaces::*;
use super::{FunctionCx, LocalRef}; use super::{FunctionCx, LocalRef};
use super::operand::{OperandRef, OperandValue}; use super::operand::{OperandRef, OperandValue};
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
use syntax::ast; use syntax::ast;
use rustc::ty::layout::{self, Align, Size}; use rustc::ty::layout::{self, Align, Size, HasTyCtxt};
use rustc::util::nodemap::FxHashMap; use rustc::util::nodemap::FxHashMap;
use rustc::ty::Ty; use rustc::ty::{self, Ty};
use rustc::ty::layout::TyLayout; use rustc::ty::layout::TyLayout;
use rustc_data_structures::small_c_str::SmallCStr; use rustc_data_structures::small_c_str::SmallCStr;
use common::{self, TypeKind}; use common::{self, TypeKind};
...@@ -365,10 +365,44 @@ fn type_padding_filler( ...@@ -365,10 +365,44 @@ fn type_padding_filler(
assert_eq!(size % unit_size, 0); assert_eq!(size % unit_size, 0);
self.type_array(self.type_from_integer(unit), size / unit_size) self.type_array(self.type_from_integer(unit), size / unit_size)
} }
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
common::type_needs_drop(self.tcx(), ty)
}
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
common::type_is_sized(self.tcx(), ty)
}
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
common::type_is_freeze(self.tcx(), ty)
}
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
use syntax_pos::DUMMY_SP;
if ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) {
return false;
}
let tail = self.tcx().struct_tail(ty);
match tail.sty {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
}
}
} }
impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn backend_type(&self, ty: TyLayout<'tcx>) -> &'ll Type { fn backend_type(&self, ty: &TyLayout<'tcx>) -> &'ll Type {
ty.llvm_type(&self) ty.llvm_type(&self)
} }
fn scalar_pair_element_backend_type<'a>(
&self,
ty: &TyLayout<'tcx>,
index: usize,
immediate: bool
) -> &'ll Type {
ty.scalar_pair_element_llvm_type(&self, index, immediate)
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册