Auto merge of #121577 - erikdesjardins:struct, r= · rust-lang/rust@e102148 (original) (raw)

`@@ -734,7 +734,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

`

734

734

`self.gcc_checked_binop(oop, typ, lhs, rhs)

`

735

735

`}

`

736

736

``

737

``

`-

fn alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> {

`

``

737

`+

fn alloca(&mut self, size: Size, align: Align) -> RValue<'gcc> {

`

``

738

`+

let ty = self.cx.type_array(self.cx.type_i8(), size.bytes()).get_aligned(align.bytes());

`

``

739

`+

// TODO(antoyo): It might be better to return a LValue, but fixing the rustc API is non-trivial.

`

``

740

`+

self.stack_var_count.set(self.stack_var_count.get() + 1);

`

``

741

`+

self.current_func().new_local(None, ty, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None)

`

``

742

`+

}

`

``

743

+

``

744

`+

fn dynamic_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> {

`

``

745

`+

unimplemented!();

`

``

746

`+

}

`

``

747

+

``

748

`+

fn typed_alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> {

`

738

749

`// FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.

`

739

750

`// Ideally, we shouldn't need to do this check.

`

740

751

`let aligned_type =

`

`@@ -749,10 +760,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

`

749

760

`self.current_func().new_local(None, aligned_type, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None)

`

750

761

`}

`

751

762

``

752

``

`-

fn byte_array_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> {

`

753

``

`-

unimplemented!();

`

754

``

`-

}

`

755

``

-

756

763

`fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {

`

757

764

`let block = self.llbb();

`

758

765

`let function = block.get_function();

`

`@@ -834,10 +841,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

`

834

841

`}

`

835

842

`else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi {

`

836

843

`let b_offset = a.size(self).align_to(b.align(self).abi);

`

837

``

`-

let pair_type = place.layout.gcc_type(self);

`

838

844

``

839

845

`let mut load = |i, scalar: &abi::Scalar, align| {

`

840

``

`-

let llptr = self.struct_gep(pair_type, place.llval, i as u64);

`

``

846

`+

let llptr = if i == 0 {

`

``

847

`+

place.llval

`

``

848

`+

} else {

`

``

849

`+

self.inbounds_gep(

`

``

850

`+

self.type_i8(),

`

``

851

`+

place.llval,

`

``

852

`+

&[self.const_usize(b_offset.bytes())],

`

``

853

`+

)

`

``

854

`+

};

`

841

855

`let llty = place.layout.scalar_pair_element_gcc_type(self, i);

`

842

856

`let load = self.load(llty, llptr, align);

`

843

857

`scalar_load_metadata(self, load, scalar);

`

`@@ -971,33 +985,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

`

971

985

` result.get_address(None)

`

972

986

`}

`

973

987

``

974

``

`-

fn struct_gep(&mut self, value_type: Type<'gcc>, ptr: RValue<'gcc>, idx: u64) -> RValue<'gcc> {

`

975

``

`-

// FIXME(antoyo): it would be better if the API only called this on struct, not on arrays.

`

976

``

`-

assert_eq!(idx as usize as u64, idx);

`

977

``

`-

let value = ptr.dereference(None).to_rvalue();

`

978

``

-

979

``

`-

if value_type.dyncast_array().is_some() {

`

980

``

`-

let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));

`

981

``

`-

let element = self.context.new_array_access(None, value, index);

`

982

``

`-

element.get_address(None)

`

983

``

`-

}

`

984

``

`-

else if let Some(vector_type) = value_type.dyncast_vector() {

`

985

``

`-

let array_type = vector_type.get_element_type().make_pointer();

`

986

``

`-

let array = self.bitcast(ptr, array_type);

`

987

``

`-

let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));

`

988

``

`-

let element = self.context.new_array_access(None, array, index);

`

989

``

`-

element.get_address(None)

`

990

``

`-

}

`

991

``

`-

else if let Some(struct_type) = value_type.is_struct() {

`

992

``

`-

// NOTE: due to opaque pointers now being used, we need to bitcast here.

`

993

``

`-

let ptr = self.bitcast_if_needed(ptr, value_type.make_pointer());

`

994

``

`-

ptr.dereference_field(None, struct_type.get_field(idx as i32)).get_address(None)

`

995

``

`-

}

`

996

``

`-

else {

`

997

``

`-

panic!("Unexpected type {:?}", value_type);

`

998

``

`-

}

`

999

``

`-

}

`

1000

``

-

1001

988

`/* Casts */

`

1002

989

`fn trunc(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {

`

1003

990

`// TODO(antoyo): check that it indeed truncate the value.

`