diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index b854addf0b1a2..36958fa706ed5 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -88,6 +88,7 @@ pub enum Repr { struct Struct { size: u64, align: u64, + packed: bool, fields: ~[ty::t] } @@ -109,17 +110,18 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { } let repr = @match ty::get(t).sty { ty::ty_tup(ref elems) => { - Univariant(mk_struct(cx, *elems), false) + Univariant(mk_struct(cx, *elems, false), false) } ty::ty_struct(def_id, ref substs) => { let fields = ty::lookup_struct_fields(cx.tcx, def_id); let ftys = do fields.map |field| { ty::lookup_field_type(cx.tcx, def_id, field.id, substs) }; + let packed = ty::lookup_packed(cx.tcx, def_id); let dtor = ty::ty_dtor(cx.tcx, def_id).is_present(); let ftys = if dtor { ftys + [ty::mk_bool(cx.tcx)] } else { ftys }; - Univariant(mk_struct(cx, ftys), dtor) + Univariant(mk_struct(cx, ftys, packed), dtor) } ty::ty_enum(def_id, ref substs) => { struct Case { discr: int, tys: ~[ty::t] }; @@ -132,7 +134,7 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { }; if cases.len() == 0 { // Uninhabitable; represent as unit - Univariant(mk_struct(cx, ~[]), false) + Univariant(mk_struct(cx, ~[], false), false) } else if cases.all(|c| c.tys.len() == 0) { // All bodies empty -> intlike let discrs = cases.map(|c| c.discr); @@ -140,7 +142,7 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { } else if cases.len() == 1 { // Equivalent to a struct/tuple/newtype. assert!(cases[0].discr == 0); - Univariant(mk_struct(cx, cases[0].tys), false) + Univariant(mk_struct(cx, cases[0].tys, false), false) } else { // The general case. Since there's at least one // non-empty body, explicit discriminants should have @@ -151,7 +153,7 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { ty::item_path_str(cx.tcx, def_id))) } let discr = ~[ty::mk_int(cx.tcx)]; - General(cases.map(|c| mk_struct(cx, discr + c.tys))) + General(cases.map(|c| mk_struct(cx, discr + c.tys, false))) } } _ => cx.sess.bug(~"adt::represent_type called on non-ADT type") @@ -160,12 +162,13 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { return repr; } -fn mk_struct(cx: @CrateContext, tys: &[ty::t]) -> Struct { +fn mk_struct(cx: @CrateContext, tys: &[ty::t], packed: bool) -> Struct { let lltys = tys.map(|&ty| type_of::sizing_type_of(cx, ty)); - let llty_rec = T_struct(lltys); + let llty_rec = T_struct(lltys, packed); Struct { size: machine::llsize_of_alloc(cx, llty_rec) /*bad*/as u64, align: machine::llalign_of_min(cx, llty_rec) /*bad*/as u64, + packed: packed, fields: vec::from_slice(tys) } } @@ -358,7 +361,8 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint, let val = if needs_cast { let real_llty = T_struct(st.fields.map( - |&ty| type_of::type_of(ccx, ty))); + |&ty| type_of::type_of(ccx, ty)), + st.packed); PointerCast(bcx, val, T_ptr(real_llty)) } else { val diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index b3b23a8730d1a..cbcefdd5fdb77 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -108,7 +108,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { } else if numOutputs == 1 { val_ty(outputs[0]) } else { - T_struct(outputs.map(|o| val_ty(*o))) + T_struct(outputs.map(|o| val_ty(*o)), false) }; let dialect = match ia.dialect { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 2eb7f8332ca92..d94f2bf3c2fe5 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -938,7 +938,7 @@ pub fn get_landing_pad(bcx: block) -> BasicBlockRef { // The landing pad return type (the type being propagated). Not sure what // this represents but it's determined by the personality function and // this is what the EH proposal example uses. - let llretty = T_struct(~[T_ptr(T_i8()), T_i32()]); + let llretty = T_struct(~[T_ptr(T_i8()), T_i32()], false); // The exception handling personality function. This is the C++ // personality function __gxx_personality_v0, wrapped in our naming // convention. @@ -2837,7 +2837,7 @@ pub fn decl_gc_metadata(ccx: @CrateContext, llmod_id: &str) { } pub fn create_module_map(ccx: @CrateContext) -> ValueRef { - let elttype = T_struct(~[ccx.int_type, ccx.int_type]); + let elttype = T_struct(~[ccx.int_type, ccx.int_type], false); let maptype = T_array(elttype, ccx.module_data.len() + 1); let map = str::as_c_str(~"_rust_mod_map", |buf| { unsafe { @@ -2877,7 +2877,7 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, }; let sym_name = ~"_rust_crate_map_" + mapname; let arrtype = T_array(int_type, n_subcrates as uint); - let maptype = T_struct(~[T_i32(), T_ptr(T_i8()), int_type, arrtype]); + let maptype = T_struct(~[T_i32(), T_ptr(T_i8()), int_type, arrtype], false); let map = str::as_c_str(sym_name, |buf| { unsafe { llvm::LLVMAddGlobal(llmod, maptype, buf) diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index a16b3672b7afe..1b94e990545ea 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -12,6 +12,7 @@ use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; use lib::llvm::struct_tys; use lib::llvm::TypeRef; use lib::llvm::{Attribute, StructRetAttribute}; +use lib::llvm::True; use middle::trans::cabi::{ABIInfo, FnType, LLVMType}; use middle::trans::common::{T_i8, T_i16, T_i32, T_i64}; use middle::trans::common::{T_array, T_ptr, T_void}; @@ -39,8 +40,12 @@ fn ty_align(ty: TypeRef) -> uint { Float => 4, Double => 8, Struct => { - do vec::foldl(1, struct_tys(ty)) |a, t| { - uint::max(a, ty_align(*t)) + if llvm::LLVMIsPackedStruct(ty) == True { + 1 + } else { + do vec::foldl(1, struct_tys(ty)) |a, t| { + uint::max(a, ty_align(*t)) + } } } Array => { @@ -62,10 +67,16 @@ fn ty_size(ty: TypeRef) -> uint { Float => 4, Double => 8, Struct => { - let size = do vec::foldl(0, struct_tys(ty)) |s, t| { - align(s, *t) + ty_size(*t) - }; - align(size, ty) + if llvm::LLVMIsPackedStruct(ty) == True { + do vec::foldl(0, struct_tys(ty)) |s, t| { + s + ty_size(*t) + } + } else { + let size = do vec::foldl(0, struct_tys(ty)) |s, t| { + align(s, *t) + ty_size(*t) + }; + align(size, ty) + } } Array => { let len = llvm::LLVMGetArrayLength(ty) as uint; diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 1e05cf258c719..ce37455560b5c 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -14,6 +14,7 @@ use core::libc::c_uint; use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double}; use lib::llvm::{Struct, Array, Attribute}; use lib::llvm::{StructRetAttribute}; +use lib::llvm::True; use middle::trans::common::*; use middle::trans::cabi::*; @@ -49,8 +50,12 @@ fn ty_align(ty: TypeRef) -> uint { Float => 4, Double => 8, Struct => { - do vec::foldl(1, struct_tys(ty)) |a, t| { - uint::max(a, ty_align(*t)) + if llvm::LLVMIsPackedStruct(ty) == True { + 1 + } else { + do vec::foldl(1, struct_tys(ty)) |a, t| { + uint::max(a, ty_align(*t)) + } } } Array => { @@ -72,10 +77,16 @@ fn ty_size(ty: TypeRef) -> uint { Float => 4, Double => 8, Struct => { - let size = do vec::foldl(0, struct_tys(ty)) |s, t| { - align(s, *t) + ty_size(*t) - }; - align(size, ty) + if llvm::LLVMIsPackedStruct(ty) == True { + do vec::foldl(0, struct_tys(ty)) |s, t| { + s + ty_size(*t) + } + } else { + let size = do vec::foldl(0, struct_tys(ty)) |s, t| { + align(s, *t) + ty_size(*t) + }; + align(size, ty) + } } Array => { let len = llvm::LLVMGetArrayLength(ty) as uint; @@ -174,7 +185,7 @@ fn struct_ty(ty: TypeRef, fields.push(ty); } - return T_struct(fields); + return T_struct(fields, false); } enum MIPS_ABIInfo { MIPS_ABIInfo } diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 896ebd1625755..0e4bf5ce574a1 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -15,6 +15,7 @@ use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double}; use lib::llvm::{Struct, Array, Attribute}; use lib::llvm::{StructRetAttribute, ByValAttribute}; use lib::llvm::struct_tys; +use lib::llvm::True; use middle::trans::common::*; use middle::trans::cabi::*; @@ -76,8 +77,12 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { Float => 4, Double => 8, Struct => { - do vec::foldl(1, struct_tys(ty)) |a, t| { + if llvm::LLVMIsPackedStruct(ty) == True { + 1 + } else { + do vec::foldl(1, struct_tys(ty)) |a, t| { uint::max(a, ty_align(*t)) + } } } Array => { @@ -99,10 +104,16 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { Float => 4, Double => 8, Struct => { - let size = do vec::foldl(0, struct_tys(ty)) |s, t| { + if llvm::LLVMIsPackedStruct(ty) == True { + do vec::foldl(0, struct_tys(ty)) |s, t| { + s + ty_size(*t) + } + } else { + let size = do vec::foldl(0, struct_tys(ty)) |s, t| { align(s, *t) + ty_size(*t) - }; - align(size, ty) + }; + align(size, ty) + } } Array => { let len = llvm::LLVMGetArrayLength(ty) as uint; @@ -308,7 +319,7 @@ fn llreg_ty(cls: &[x86_64_reg_class]) -> TypeRef { } i += 1u; } - return T_struct(tys); + return T_struct(tys, false); } } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 2cfd7a25d6823..4701a166ea766 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -765,7 +765,7 @@ pub fn T_void() -> TypeRef { } pub fn T_nil() -> TypeRef { - return T_struct(~[]) + return T_struct(~[], false) } pub fn T_metadata() -> TypeRef { unsafe { return llvm::LLVMMetadataType(); } } @@ -848,7 +848,7 @@ pub fn T_fn(inputs: &[TypeRef], output: TypeRef) -> TypeRef { } pub fn T_fn_pair(cx: @CrateContext, tfn: TypeRef) -> TypeRef { - return T_struct(~[T_ptr(tfn), T_opaque_cbox_ptr(cx)]); + return T_struct(~[T_ptr(tfn), T_opaque_cbox_ptr(cx)], false); } pub fn T_ptr(t: TypeRef) -> TypeRef { @@ -863,11 +863,11 @@ pub fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef { } } -pub fn T_struct(elts: &[TypeRef]) -> TypeRef { +pub fn T_struct(elts: &[TypeRef], packed: bool) -> TypeRef { unsafe { return llvm::LLVMStructType(to_ptr(elts), elts.len() as c_uint, - False); + packed as Bool); } } @@ -878,16 +878,16 @@ pub fn T_named_struct(name: &str) -> TypeRef { } } -pub fn set_struct_body(t: TypeRef, elts: &[TypeRef]) { +pub fn set_struct_body(t: TypeRef, elts: &[TypeRef], packed: bool) { unsafe { llvm::LLVMStructSetBody(t, to_ptr(elts), elts.len() as c_uint, - False); + packed as Bool); } } -pub fn T_empty_struct() -> TypeRef { return T_struct(~[]); } +pub fn T_empty_struct() -> TypeRef { return T_struct(~[], false); } // A vtable is, in reality, a vtable pointer followed by zero or more pointers // to tydescs and other vtables that it closes over. But the types and number @@ -913,7 +913,7 @@ pub fn T_task(targ_cfg: @session::config) -> TypeRef { let elems = ~[t_int, t_int, t_int, t_int, t_int, t_int, t_int, t_int]; - set_struct_body(t, elems); + set_struct_body(t, elems, false); return t; } @@ -956,7 +956,7 @@ pub fn T_tydesc(targ_cfg: @session::config) -> TypeRef { ~[int_type, int_type, glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, T_ptr(T_i8()), T_ptr(T_i8())]; - set_struct_body(tydesc, elems); + set_struct_body(tydesc, elems, false); return tydesc; } @@ -969,8 +969,9 @@ pub fn T_array(t: TypeRef, n: uint) -> TypeRef { // Interior vector. pub fn T_vec2(targ_cfg: @session::config, t: TypeRef) -> TypeRef { return T_struct(~[T_int(targ_cfg), // fill - T_int(targ_cfg), // alloc - T_array(t, 0u)]); // elements + T_int(targ_cfg), // alloc + T_array(t, 0u)], // elements + false); } pub fn T_vec(ccx: @CrateContext, t: TypeRef) -> TypeRef { @@ -1001,11 +1002,11 @@ pub fn T_box_header_fields(cx: @CrateContext) -> ~[TypeRef] { } pub fn T_box_header(cx: @CrateContext) -> TypeRef { - return T_struct(T_box_header_fields(cx)); + return T_struct(T_box_header_fields(cx), false); } pub fn T_box(cx: @CrateContext, t: TypeRef) -> TypeRef { - return T_struct(vec::append(T_box_header_fields(cx), ~[t])); + return T_struct(vec::append(T_box_header_fields(cx), ~[t]), false); } pub fn T_box_ptr(t: TypeRef) -> TypeRef { @@ -1023,7 +1024,7 @@ pub fn T_opaque_box_ptr(cx: @CrateContext) -> TypeRef { } pub fn T_unique(cx: @CrateContext, t: TypeRef) -> TypeRef { - return T_struct(vec::append(T_box_header_fields(cx), ~[t])); + return T_struct(vec::append(T_box_header_fields(cx), ~[t]), false); } pub fn T_unique_ptr(t: TypeRef) -> TypeRef { @@ -1033,12 +1034,12 @@ pub fn T_unique_ptr(t: TypeRef) -> TypeRef { } pub fn T_port(cx: @CrateContext, _t: TypeRef) -> TypeRef { - return T_struct(~[cx.int_type]); // Refcount + return T_struct(~[cx.int_type], false); // Refcount } pub fn T_chan(cx: @CrateContext, _t: TypeRef) -> TypeRef { - return T_struct(~[cx.int_type]); // Refcount + return T_struct(~[cx.int_type], false); // Refcount } @@ -1056,21 +1057,22 @@ pub fn T_enum_discrim(cx: @CrateContext) -> TypeRef { } pub fn T_captured_tydescs(cx: @CrateContext, n: uint) -> TypeRef { - return T_struct(vec::from_elem::(n, T_ptr(cx.tydesc_type))); + return T_struct(vec::from_elem::(n, T_ptr(cx.tydesc_type)), false); } pub fn T_opaque_trait(cx: @CrateContext, store: ty::TraitStore) -> TypeRef { match store { ty::BoxTraitStore => { - T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)]) + T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)], false) } ty::UniqTraitStore => { T_struct(~[T_ptr(cx.tydesc_type), T_unique_ptr(T_unique(cx, T_i8())), - T_ptr(cx.tydesc_type)]) + T_ptr(cx.tydesc_type)], + false) } ty::RegionTraitStore(_) => { - T_struct(~[T_ptr(cx.tydesc_type), T_ptr(T_i8())]) + T_struct(~[T_ptr(cx.tydesc_type), T_ptr(T_i8())], false) } } } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 7dc2e385e2cf6..387caa4d8d31f 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -106,7 +106,8 @@ fn shim_types(ccx: @CrateContext, id: ast::node_id) -> ShimTypes { }; let llsig = foreign_signature(ccx, &fn_sig); let bundle_ty = T_struct(vec::append_one(copy llsig.llarg_tys, - T_ptr(llsig.llret_ty))); + T_ptr(llsig.llret_ty)), + false); let ret_def = !ty::type_is_bot(fn_sig.output) && !ty::type_is_nil(fn_sig.output); diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index 1b9f7bae0e93f..cd90f964e452e 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -142,9 +142,9 @@ pub fn static_size_of_enum(cx: @CrateContext, t: ty::t) -> uint { debug!("static_size_of_enum: variant %s type %s", *cx.tcx.sess.str_of(variant.name), - ty_str(cx.tn, T_struct(lltypes))); + ty_str(cx.tn, T_struct(lltypes, false))); - let this_size = llsize_of_real(cx, T_struct(lltypes)); + let this_size = llsize_of_real(cx, T_struct(lltypes, false)); if max_size < this_size { max_size = this_size; } diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index a9381647b3326..1c94fe2842219 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -128,11 +128,11 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef { ty::ty_estr(ty::vstore_slice(*)) | ty::ty_evec(_, ty::vstore_slice(*)) => { - T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]) + T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())], false) } ty::ty_bare_fn(*) => T_ptr(T_i8()), - ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]), + ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())], false), ty::ty_trait(_, _, store) => T_opaque_trait(cx, store), ty::ty_estr(ty::vstore_fixed(size)) => T_array(T_i8(), size), @@ -142,9 +142,15 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef { ty::ty_unboxed_vec(mt) => T_vec(cx, sizing_type_of(cx, mt.ty)), - ty::ty_tup(*) | ty::ty_struct(*) | ty::ty_enum(*) => { + ty::ty_tup(*) | ty::ty_enum(*) => { let repr = adt::represent_type(cx, t); - T_struct(adt::sizing_fields_of(cx, repr)) + T_struct(adt::sizing_fields_of(cx, repr), false) + } + + ty::ty_struct(did, _) => { + let repr = adt::represent_type(cx, t); + let packed = ty::lookup_packed(cx.tcx, did); + T_struct(adt::sizing_fields_of(cx, repr), packed) } ty::ty_self(_) | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => { @@ -223,12 +229,14 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { ty::ty_evec(ref mt, ty::vstore_slice(_)) => { T_struct(~[T_ptr(type_of(cx, mt.ty)), - T_uint_ty(cx, ast::ty_u)]) + T_uint_ty(cx, ast::ty_u)], + false) } ty::ty_estr(ty::vstore_slice(_)) => { T_struct(~[T_ptr(T_i8()), - T_uint_ty(cx, ast::ty_u)]) + T_uint_ty(cx, ast::ty_u)], + false) } ty::ty_estr(ty::vstore_fixed(n)) => { @@ -245,7 +253,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { ty::ty_type => T_ptr(cx.tydesc_type), ty::ty_tup(*) => { let repr = adt::represent_type(cx, t); - T_struct(adt::fields_of(cx, repr)) + T_struct(adt::fields_of(cx, repr), false) } ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx), ty::ty_struct(did, ref substs) => { @@ -268,9 +276,17 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { // If this was an enum or struct, fill in the type now. match ty::get(t).sty { - ty::ty_enum(*) | ty::ty_struct(*) => { + ty::ty_enum(*) => { let repr = adt::represent_type(cx, t); - common::set_struct_body(llty, adt::fields_of(cx, repr)); + common::set_struct_body(llty, adt::fields_of(cx, repr), + false); + } + + ty::ty_struct(did, _) => { + let repr = adt::represent_type(cx, t); + let packed = ty::lookup_packed(cx.tcx, did); + common::set_struct_body(llty, adt::fields_of(cx, repr), + packed); } _ => () } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 742153124346a..335c9824354d2 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -44,6 +44,7 @@ use std::smallintmap::SmallIntMap; use syntax::ast::*; use syntax::ast_util::{is_local, local_def}; use syntax::ast_util; +use syntax::attr; use syntax::codemap::span; use syntax::codemap; use syntax::print::pprust; @@ -3933,6 +3934,28 @@ pub fn lookup_trait_def(cx: ctxt, did: ast::def_id) -> @ty::TraitDef { } } +// Determine whether an item is annotated with #[packed] or not +pub fn lookup_packed(tcx: ctxt, + did: def_id) -> bool { + if is_local(did) { + match tcx.items.find(&did.node) { + Some( + &ast_map::node_item(@ast::item { + attrs: ref attrs, + _ + }, _)) => attr::attrs_contains_name(*attrs, "packed"), + _ => tcx.sess.bug(fmt!("lookup_packed: %? is not an item", + did)) + } + } else { + let mut ret = false; + do csearch::get_item_attrs(tcx.cstore, did) |meta_items| { + ret = attr::contains_name(meta_items, "packed"); + } + ret + } +} + // Look up a field ID, whether or not it's local // Takes a list of type substs in case the struct is generic pub fn lookup_field_type(tcx: ctxt,