use crate::rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods};
use rustc_middle::bug;
use rustc_middle::ty::{self, Ty, TypeFoldable};
-use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout};
+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, LayoutOf, Pointer, PointeeInfo, Size, TyAndLayoutMethods, Variants};
+use rustc_target::abi::{self, Abi, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
use crate::abi::{FnAbiGccExt, GccType};
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str
if !cx.sess().fewer_names() =>
{
- let mut name = with_no_trimmed_paths(|| layout.ty.to_string());
+ let mut name = with_no_trimmed_paths!(layout.ty.to_string());
if let (&ty::Adt(def, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants)
{
- if def.is_enum() && !def.variants.is_empty() {
- write!(&mut name, "::{}", def.variants[index].ident).unwrap();
+ if def.is_enum() && !def.variants().is_empty() {
+ write!(&mut name, "::{}", def.variant(index).name).unwrap();
}
}
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
// If `Some` is returned then a named struct is created in LLVM. Name collisions are
// avoided by LLVM (with increasing suffixes). If rustc doesn't generate names then that
// can improve perf.
- // FIXME: I don't think that's true for libgccjit.
+ // FIXME(antoyo): I don't think that's true for libgccjit.
Some(String::new())
}
_ => None,
/// 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> {
if let Abi::Scalar(ref scalar) = self.abi {
// Use a different cache for scalars because pointers to DSTs
ty::Adt(def, _) if def.is_box() => {
cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).gcc_type(cx, true))
}
- ty::FnPtr(sig) => cx.fn_ptr_backend_type(&FnAbi::of_fn_ptr(cx, sig, &[])),
+ 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),
};
cx.scalar_types.borrow_mut().insert(self.ty, ty);
return ty;
}
- //debug!("gcc_type({:#?})", self);
-
assert!(!self.ty.has_escaping_bound_vars(), "{:?} has escaping bound vars", self.ty);
// Make sure lifetimes are erased, to avoid generating distinct LLVM
else {
uncached_gcc_type(cx, *self, &mut defer)
};
- //debug!("--> mapped {:#?} to ty={:?}", self, ty);
cx.types.borrow_mut().insert((self.ty, variant_index), ty);
if let Some((ty, layout)) = defer {
- //TODO: do we still need this conditions and the set_fields parameter?
- //if set_fields {
- let (fields, packed) = struct_fields(cx, layout);
- cx.set_struct_body(ty, &fields, packed);
- /*}
- else {
- // Since we might be trying to generate a type containing another type which is not
- // completely generated yet, we don't set the fields right now, but we save the
- // type to set the fields later.
- cx.types_with_fields_to_set.borrow_mut().insert(ty.as_type(), (ty, layout));
- }*/
+ let (fields, packed) = struct_fields(cx, layout);
+ cx.set_struct_body(ty, &fields, packed);
}
ty
}
fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc> {
- match scalar.value {
+ match scalar.primitive() {
Int(i, true) => cx.type_from_integer(i),
Int(i, false) => cx.type_from_unsigned_integer(i),
F32 => cx.type_f32(),
}
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize, immediate: bool) -> Type<'gcc> {
- // TODO: remove llvm hack:
+ // TODO(antoyo): remove llvm hack:
// HACK(eddyb) special-case fat pointers until LLVM removes
// 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);
}
- ty::Adt(def, _) if def.is_box() => {
+ // only wide pointer boxes are handled as pointers
+ // thin pointer boxes with scalar allocators are handled by the general logic below
+ ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
let ptr_ty = cx.tcx.mk_mut_ptr(self.ty.boxed_ty());
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
}
// immediate, just like `bool` is typically `i8` in memory and only `i1`
// when immediate. We need to load/store `bool` as `i8` to avoid
// crippling LLVM optimizations or triggering other LLVM bugs with `i1`.
- // TODO: this bugs certainly don't happen in this case since the bool type is used instead of i1.
- if /*immediate &&*/ scalar.is_bool() {
+ // TODO(antoyo): this bugs certainly don't happen in this case since the bool type is used instead of i1.
+ if scalar.is_bool() {
return cx.type_i1();
}
Size::ZERO
}
else {
- a.value.size(cx).align_to(b.value.align(cx).abi)
+ a.size(cx).align_to(b.align(cx).abi)
};
self.scalar_gcc_type_at(cx, scalar, offset)
}
return pointee;
}
- let result = Ty::pointee_info_at(*self, cx, offset);
+ let result = Ty::ty_and_layout_pointee_info_at(*self, cx, offset);
cx.pointee_infos.borrow_mut().insert((self.ty, offset), result);
result
fn reg_backend_type(&self, _ty: &Reg) -> Type<'gcc> {
unimplemented!();
- //ty.gcc_type(self)
}
fn fn_decl_backend_type(&self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {
- // FIXME: return correct type.
+ // FIXME(antoyo): return correct type.
self.type_void()
- //fn_abi.gcc_type(self)
}
}