diff options
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/type_of.rs')
-rw-r--r-- | compiler/rustc_codegen_gcc/src/type_of.rs | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index ea2ce7650..5df8c1a20 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -6,7 +6,7 @@ use rustc_middle::bug; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_target::abi::{self, Abi, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants}; +use rustc_target::abi::{self, Abi, Align, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; use crate::abi::{FnAbiGccExt, GccType}; @@ -50,11 +50,25 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>, defer: &mut Option<(Struct<'gcc>, TyAndLayout<'tcx>)>) -> Type<'gcc> { +impl<'a, 'tcx> CodegenCx<'a, 'tcx> { + pub fn align_of(&self, ty: Ty<'tcx>) -> Align { + self.layout_of(ty).align.abi + } +} + +fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>, defer: &mut Option<(Struct<'gcc>, TyAndLayout<'tcx>)>) -> Type<'gcc> { match layout.abi { Abi::Scalar(_) => bug!("handled elsewhere"), Abi::Vector { ref element, count } => { let element = layout.scalar_gcc_type_at(cx, element, Size::ZERO); + let element = + // NOTE: gcc doesn't allow pointer types in vectors. + if element.get_pointee().is_some() { + cx.usize_type + } + else { + element + }; return cx.context.new_vector_type(element, count); }, Abi::ScalarPair(..) => { @@ -114,7 +128,7 @@ pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLa }, } } - FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).gcc_type(cx, true), count), + FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).gcc_type(cx), count), FieldsShape::Arbitrary { .. } => match name { None => { @@ -133,7 +147,7 @@ pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLa pub trait LayoutGccExt<'tcx> { fn is_gcc_immediate(&self) -> bool; fn is_gcc_scalar_pair(&self) -> bool; - fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, set_fields: bool) -> Type<'gcc>; + fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc>; fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize, immediate: bool) -> Type<'gcc>; @@ -168,8 +182,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { /// with the inner-most trailing unsized field using the "minimal unit" /// of that field's type - this is useful for taking the address of /// that field and ensuring the struct has the right alignment. - //TODO(antoyo): do we still need the set_fields parameter? - fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, set_fields: bool) -> Type<'gcc> { + fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { if let Abi::Scalar(ref scalar) = self.abi { // Use a different cache for scalars because pointers to DSTs // can be either fat or thin (data pointers of fat pointers). @@ -179,10 +192,10 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { let ty = match *self.ty.kind() { ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { - cx.type_ptr_to(cx.layout_of(ty).gcc_type(cx, set_fields)) + cx.type_ptr_to(cx.layout_of(ty).gcc_type(cx)) } ty::Adt(def, _) if def.is_box() => { - cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).gcc_type(cx, true)) + cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).gcc_type(cx)) } ty::FnPtr(sig) => cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, ty::List::empty())), _ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO), @@ -199,13 +212,6 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { }; let cached_type = cx.types.borrow().get(&(self.ty, variant_index)).cloned(); if let Some(ty) = cached_type { - let type_to_set_fields = cx.types_with_fields_to_set.borrow_mut().remove(&ty); - if let Some((struct_type, layout)) = type_to_set_fields { - // Since we might be trying to generate a type containing another type which is not - // completely generated yet, we deferred setting the fields until now. - let (fields, packed) = struct_fields(cx, layout); - cx.set_struct_body(struct_type, &fields, packed); - } return ty; } @@ -222,7 +228,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { if let Some(v) = variant_index { layout = layout.for_variant(cx, v); } - layout.gcc_type(cx, true) + layout.gcc_type(cx) } else { uncached_gcc_type(cx, *self, &mut defer) @@ -230,9 +236,9 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { cx.types.borrow_mut().insert((self.ty, variant_index), ty); - if let Some((ty, layout)) = defer { + if let Some((deferred_ty, layout)) = defer { let (fields, packed) = struct_fields(cx, layout); - cx.set_struct_body(ty, &fields, packed); + cx.set_struct_body(deferred_ty, &fields, packed); } ty @@ -244,7 +250,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { return cx.type_i1(); } } - self.gcc_type(cx, true) + self.gcc_type(cx) } fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc> { @@ -273,7 +279,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { // pointee types, to avoid bitcasting every `OperandRef::deref`. match self.ty.kind() { ty::Ref(..) | ty::RawPtr(_) => { - return self.field(cx, index).gcc_type(cx, true); + return self.field(cx, index).gcc_type(cx); } // only wide pointer boxes are handled as pointers // thin pointer boxes with scalar allocators are handled by the general logic below @@ -343,7 +349,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Type<'gcc> { - layout.gcc_type(self, true) + layout.gcc_type(self) } fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Type<'gcc> { |