mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Added default impl for DerivedTypeMethods + empty impl for Cranelift BaseTypeMethods
This commit is contained in:
parent
54dd3a47fd
commit
b25b804013
@ -18,16 +18,12 @@ use context::CodegenCx;
|
||||
use rustc_codegen_ssa::interfaces::*;
|
||||
use value::Value;
|
||||
|
||||
|
||||
use syntax::ast;
|
||||
use rustc::ty::layout::{self, Align, Size, HasTyCtxt};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::Ty;
|
||||
use rustc::ty::layout::TyLayout;
|
||||
use rustc_target::abi::call::{CastTarget, FnType, Reg};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use common;
|
||||
use rustc_codegen_ssa;
|
||||
use rustc_codegen_ssa::common::TypeKind;
|
||||
use type_of::LayoutLlvmExt;
|
||||
use abi::{LlvmType, FnTypeExt};
|
||||
@ -108,6 +104,10 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn type_isize(&self) -> &'ll Type {
|
||||
self.isize_ty
|
||||
}
|
||||
|
||||
fn type_f32(&self) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMFloatTypeInContext(self.llcx)
|
||||
@ -274,121 +274,6 @@ impl Type {
|
||||
}
|
||||
}
|
||||
|
||||
impl DerivedTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
fn type_bool(&self) -> &'ll Type {
|
||||
self.type_i8()
|
||||
}
|
||||
|
||||
fn type_i8p(&self) -> &'ll Type {
|
||||
self.type_ptr_to(self.type_i8())
|
||||
}
|
||||
|
||||
fn type_isize(&self) -> &'ll Type {
|
||||
self.isize_ty
|
||||
}
|
||||
|
||||
fn type_int(&self) -> &'ll Type {
|
||||
match &self.sess().target.target.target_c_int_width[..] {
|
||||
"16" => self.type_i16(),
|
||||
"32" => self.type_i32(),
|
||||
"64" => self.type_i64(),
|
||||
width => bug!("Unsupported target_c_int_width: {}", width),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_int_from_ty(
|
||||
&self,
|
||||
t: ast::IntTy
|
||||
) -> &'ll Type {
|
||||
match t {
|
||||
ast::IntTy::Isize => self.isize_ty,
|
||||
ast::IntTy::I8 => self.type_i8(),
|
||||
ast::IntTy::I16 => self.type_i16(),
|
||||
ast::IntTy::I32 => self.type_i32(),
|
||||
ast::IntTy::I64 => self.type_i64(),
|
||||
ast::IntTy::I128 => self.type_i128(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_uint_from_ty(
|
||||
&self,
|
||||
t: ast::UintTy
|
||||
) -> &'ll Type {
|
||||
match t {
|
||||
ast::UintTy::Usize => self.isize_ty,
|
||||
ast::UintTy::U8 => self.type_i8(),
|
||||
ast::UintTy::U16 => self.type_i16(),
|
||||
ast::UintTy::U32 => self.type_i32(),
|
||||
ast::UintTy::U64 => self.type_i64(),
|
||||
ast::UintTy::U128 => self.type_i128(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_float_from_ty(
|
||||
&self,
|
||||
t: ast::FloatTy
|
||||
) -> &'ll Type {
|
||||
match t {
|
||||
ast::FloatTy::F32 => self.type_f32(),
|
||||
ast::FloatTy::F64 => self.type_f64(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_from_integer(&self, i: layout::Integer) -> &'ll Type {
|
||||
use rustc::ty::layout::Integer::*;
|
||||
match i {
|
||||
I8 => self.type_i8(),
|
||||
I16 => self.type_i16(),
|
||||
I32 => self.type_i32(),
|
||||
I64 => self.type_i64(),
|
||||
I128 => self.type_i128(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_pointee_for_abi_align(&self, align: Align) -> &'ll Type {
|
||||
// FIXME(eddyb) We could find a better approximation if ity.align < align.
|
||||
let ity = layout::Integer::approximate_abi_align(self, align);
|
||||
self.type_from_integer(ity)
|
||||
}
|
||||
|
||||
fn type_padding_filler(
|
||||
&self,
|
||||
size: Size,
|
||||
align: Align
|
||||
) -> &'ll Type {
|
||||
let unit = layout::Integer::approximate_abi_align(self, align);
|
||||
let size = size.bytes();
|
||||
let unit_size = unit.size().bytes();
|
||||
assert_eq!(size % unit_size, 0);
|
||||
self.type_array(self.type_from_integer(unit), size / unit_size)
|
||||
}
|
||||
|
||||
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
|
||||
rustc_codegen_ssa::common::type_needs_drop(self.tcx(), ty)
|
||||
}
|
||||
|
||||
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||
rustc_codegen_ssa::common::type_is_sized(self.tcx(), ty)
|
||||
}
|
||||
|
||||
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
||||
rustc_codegen_ssa::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> {
|
||||
fn backend_type(&self, layout: TyLayout<'tcx>) -> &'ll Type {
|
||||
|
@ -35,7 +35,7 @@ pub trait BackendTypes {
|
||||
}
|
||||
|
||||
pub trait Backend<'tcx>:
|
||||
BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
|
||||
Sized + BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -8,13 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::misc::MiscMethods;
|
||||
use super::Backend;
|
||||
use super::HasCodegen;
|
||||
use common::TypeKind;
|
||||
use common::{self, TypeKind};
|
||||
use mir::place::PlaceRef;
|
||||
use rustc::ty::layout::TyLayout;
|
||||
use rustc::ty::layout::{self, Align, Size};
|
||||
use rustc::ty::Ty;
|
||||
use rustc::ty::layout::{self, Align, Size, TyLayout};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg};
|
||||
use std::cell::RefCell;
|
||||
@ -32,6 +32,7 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
|
||||
|
||||
// Creates an integer type with the given number of bits, e.g. i24
|
||||
fn type_ix(&self, num_bits: u64) -> Self::Type;
|
||||
fn type_isize(&self) -> Self::Type;
|
||||
|
||||
fn type_f32(&self) -> Self::Type;
|
||||
fn type_f64(&self) -> Self::Type;
|
||||
@ -61,30 +62,109 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
|
||||
fn scalar_lltypes(&self) -> &RefCell<FxHashMap<Ty<'tcx>, Self::Type>>;
|
||||
}
|
||||
|
||||
pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> {
|
||||
fn type_bool(&self) -> Self::Type;
|
||||
fn type_i8p(&self) -> Self::Type;
|
||||
fn type_isize(&self) -> Self::Type;
|
||||
fn type_int(&self) -> Self::Type;
|
||||
fn type_int_from_ty(&self, t: ast::IntTy) -> Self::Type;
|
||||
fn type_uint_from_ty(&self, t: ast::UintTy) -> Self::Type;
|
||||
fn type_float_from_ty(&self, t: ast::FloatTy) -> Self::Type;
|
||||
fn type_from_integer(&self, i: layout::Integer) -> Self::Type;
|
||||
pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
|
||||
fn type_bool(&self) -> Self::Type {
|
||||
self.type_i8()
|
||||
}
|
||||
|
||||
/// Return a LLVM type that has at most the required alignment,
|
||||
/// as a conservative approximation for unknown pointee types.
|
||||
fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
|
||||
fn type_i8p(&self) -> Self::Type {
|
||||
self.type_ptr_to(self.type_i8())
|
||||
}
|
||||
|
||||
fn type_int(&self) -> Self::Type {
|
||||
match &self.sess().target.target.target_c_int_width[..] {
|
||||
"16" => self.type_i16(),
|
||||
"32" => self.type_i32(),
|
||||
"64" => self.type_i64(),
|
||||
width => bug!("Unsupported target_c_int_width: {}", width),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_int_from_ty(&self, t: ast::IntTy) -> Self::Type {
|
||||
match t {
|
||||
ast::IntTy::Isize => self.type_isize(),
|
||||
ast::IntTy::I8 => self.type_i8(),
|
||||
ast::IntTy::I16 => self.type_i16(),
|
||||
ast::IntTy::I32 => self.type_i32(),
|
||||
ast::IntTy::I64 => self.type_i64(),
|
||||
ast::IntTy::I128 => self.type_i128(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_uint_from_ty(&self, t: ast::UintTy) -> Self::Type {
|
||||
match t {
|
||||
ast::UintTy::Usize => self.type_isize(),
|
||||
ast::UintTy::U8 => self.type_i8(),
|
||||
ast::UintTy::U16 => self.type_i16(),
|
||||
ast::UintTy::U32 => self.type_i32(),
|
||||
ast::UintTy::U64 => self.type_i64(),
|
||||
ast::UintTy::U128 => self.type_i128(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_float_from_ty(&self, t: ast::FloatTy) -> Self::Type {
|
||||
match t {
|
||||
ast::FloatTy::F32 => self.type_f32(),
|
||||
ast::FloatTy::F64 => self.type_f64(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_from_integer(&self, i: layout::Integer) -> Self::Type {
|
||||
use rustc::ty::layout::Integer::*;
|
||||
match i {
|
||||
I8 => self.type_i8(),
|
||||
I16 => self.type_i16(),
|
||||
I32 => self.type_i32(),
|
||||
I64 => self.type_i64(),
|
||||
I128 => self.type_i128(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type {
|
||||
// FIXME(eddyb) We could find a better approximation if ity.align < align.
|
||||
let ity = layout::Integer::approximate_abi_align(self, align);
|
||||
self.type_from_integer(ity)
|
||||
}
|
||||
|
||||
/// Return a LLVM type that has at most the required alignment,
|
||||
/// and exactly the required size, as a best-effort padding array.
|
||||
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;
|
||||
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type {
|
||||
let unit = layout::Integer::approximate_abi_align(self, align);
|
||||
let size = size.bytes();
|
||||
let unit_size = unit.size().bytes();
|
||||
assert_eq!(size % unit_size, 0);
|
||||
self.type_array(self.type_from_integer(unit), size / unit_size)
|
||||
}
|
||||
|
||||
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;
|
||||
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<T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {}
|
||||
|
||||
pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
|
||||
fn backend_type(&self, layout: TyLayout<'tcx>) -> Self::Type;
|
||||
fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type;
|
||||
@ -119,11 +199,6 @@ pub trait ArgTypeMethods<'tcx>: HasCodegen<'tcx> {
|
||||
fn memory_ty(&self, ty: &ArgType<'tcx, Ty<'tcx>>) -> Self::Type;
|
||||
}
|
||||
|
||||
pub trait TypeMethods<'tcx>:
|
||||
BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
|
||||
{
|
||||
}
|
||||
pub trait TypeMethods<'tcx>: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> {}
|
||||
|
||||
impl<T> TypeMethods<'tcx> for T where
|
||||
Self: BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
|
||||
{}
|
||||
impl<T> TypeMethods<'tcx> for T where Self: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> {}
|
||||
|
Loading…
Reference in New Issue
Block a user