rustc_trans: query LLVM types from a layout instead of a Ty.
This commit is contained in:
parent
1477119344
commit
3fd6b00082
|
@ -32,6 +32,7 @@ use cabi_nvptx64;
|
||||||
use cabi_hexagon;
|
use cabi_hexagon;
|
||||||
use mir::lvalue::LvalueRef;
|
use mir::lvalue::LvalueRef;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
use type_of::LayoutLlvmExt;
|
||||||
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
|
@ -506,7 +507,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
|
||||||
/// Get the LLVM type for an lvalue of the original Rust type of
|
/// Get the LLVM type for an lvalue of the original Rust type of
|
||||||
/// this argument/return, i.e. the result of `type_of::type_of`.
|
/// this argument/return, i.e. the result of `type_of::type_of`.
|
||||||
pub fn memory_ty(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
|
pub fn memory_ty(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
|
||||||
ccx.llvm_type_of(self.layout.ty)
|
self.layout.llvm_type(ccx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store a direct/indirect value described by this ArgType into a
|
/// Store a direct/indirect value described by this ArgType into a
|
||||||
|
@ -934,7 +935,7 @@ impl<'a, 'tcx> FnType<'tcx> {
|
||||||
} else if let Some(cast) = self.ret.cast {
|
} else if let Some(cast) = self.ret.cast {
|
||||||
cast.llvm_type(ccx)
|
cast.llvm_type(ccx)
|
||||||
} else {
|
} else {
|
||||||
ccx.immediate_llvm_type_of(self.ret.layout.ty)
|
self.ret.layout.immediate_llvm_type(ccx)
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -952,7 +953,7 @@ impl<'a, 'tcx> FnType<'tcx> {
|
||||||
} else if let Some(cast) = arg.cast {
|
} else if let Some(cast) = arg.cast {
|
||||||
cast.llvm_type(ccx)
|
cast.llvm_type(ccx)
|
||||||
} else {
|
} else {
|
||||||
ccx.immediate_llvm_type_of(arg.layout.ty)
|
arg.layout.immediate_llvm_type(ccx)
|
||||||
};
|
};
|
||||||
|
|
||||||
llargument_tys.push(llarg_ty);
|
llargument_tys.push(llarg_ty);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
use llvm::{self, ValueRef};
|
use llvm::{self, ValueRef};
|
||||||
use common::*;
|
use common::*;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
use type_of::LayoutLlvmExt;
|
||||||
use builder::Builder;
|
use builder::Builder;
|
||||||
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
@ -44,7 +45,7 @@ pub fn trans_inline_asm<'a, 'tcx>(
|
||||||
if out.is_indirect {
|
if out.is_indirect {
|
||||||
indirect_outputs.push(lvalue.load(bcx).immediate());
|
indirect_outputs.push(lvalue.load(bcx).immediate());
|
||||||
} else {
|
} else {
|
||||||
output_types.push(bcx.ccx.llvm_type_of(lvalue.layout.ty));
|
output_types.push(lvalue.layout.llvm_type(bcx.ccx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !indirect_outputs.is_empty() {
|
if !indirect_outputs.is_empty() {
|
||||||
|
|
|
@ -40,7 +40,7 @@ use rustc::middle::lang_items::StartFnLangItem;
|
||||||
use rustc::middle::trans::{Linkage, Visibility, Stats};
|
use rustc::middle::trans::{Linkage, Visibility, Stats};
|
||||||
use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes};
|
use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes};
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::layout::{Align, FullLayout};
|
use rustc::ty::layout::{self, Align, FullLayout, LayoutOf};
|
||||||
use rustc::ty::maps::Providers;
|
use rustc::ty::maps::Providers;
|
||||||
use rustc::dep_graph::{DepNode, DepKind, DepConstructor};
|
use rustc::dep_graph::{DepNode, DepKind, DepConstructor};
|
||||||
use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
|
use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
|
||||||
|
@ -68,7 +68,7 @@ use symbol_names_test;
|
||||||
use time_graph;
|
use time_graph;
|
||||||
use trans_item::{TransItem, BaseTransItemExt, TransItemExt, DefPathBasedNames};
|
use trans_item::{TransItem, BaseTransItemExt, TransItemExt, DefPathBasedNames};
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use type_of;
|
use type_of::{self, LayoutLlvmExt};
|
||||||
use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet};
|
use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet};
|
||||||
use CrateInfo;
|
use CrateInfo;
|
||||||
|
|
||||||
|
@ -228,13 +228,13 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
|
||||||
(&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }),
|
(&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }),
|
||||||
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
||||||
assert!(bcx.ccx.shared().type_is_sized(a));
|
assert!(bcx.ccx.shared().type_is_sized(a));
|
||||||
let ptr_ty = bcx.ccx.llvm_type_of(b).ptr_to();
|
let ptr_ty = bcx.ccx.layout_of(b).llvm_type(bcx.ccx).ptr_to();
|
||||||
(bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None))
|
(bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None))
|
||||||
}
|
}
|
||||||
(&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
|
(&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
|
||||||
let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty());
|
let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty());
|
||||||
assert!(bcx.ccx.shared().type_is_sized(a));
|
assert!(bcx.ccx.shared().type_is_sized(a));
|
||||||
let ptr_ty = bcx.ccx.llvm_type_of(b).ptr_to();
|
let ptr_ty = bcx.ccx.layout_of(b).llvm_type(bcx.ccx).ptr_to();
|
||||||
(bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None))
|
(bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None))
|
||||||
}
|
}
|
||||||
_ => bug!("unsize_thin_ptr: called on bad types"),
|
_ => bug!("unsize_thin_ptr: called on bad types"),
|
||||||
|
@ -371,8 +371,8 @@ pub fn from_immediate(bcx: &Builder, val: ValueRef) -> ValueRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_immediate(bcx: &Builder, val: ValueRef, ty: Ty) -> ValueRef {
|
pub fn to_immediate(bcx: &Builder, val: ValueRef, layout: layout::FullLayout) -> ValueRef {
|
||||||
if ty.is_bool() {
|
if let layout::Abi::Scalar(layout::Int(layout::I1, _)) = layout.abi {
|
||||||
bcx.trunc(val, Type::i1(bcx.ccx))
|
bcx.trunc(val, Type::i1(bcx.ccx))
|
||||||
} else {
|
} else {
|
||||||
val
|
val
|
||||||
|
|
|
@ -20,8 +20,11 @@ use consts;
|
||||||
use declare;
|
use declare;
|
||||||
use llvm::{self, ValueRef};
|
use llvm::{self, ValueRef};
|
||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
|
use type_of::LayoutLlvmExt;
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::{self, TypeFoldable};
|
use rustc::ty::{self, TypeFoldable};
|
||||||
|
use rustc::ty::layout::LayoutOf;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc_back::PanicStrategy;
|
use rustc_back::PanicStrategy;
|
||||||
|
@ -55,7 +58,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
|
|
||||||
// Create a fn pointer with the substituted signature.
|
// Create a fn pointer with the substituted signature.
|
||||||
let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(ccx, fn_ty));
|
let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(ccx, fn_ty));
|
||||||
let llptrty = ccx.llvm_type_of(fn_ptr_ty);
|
let llptrty = ccx.layout_of(fn_ptr_ty).llvm_type(ccx);
|
||||||
|
|
||||||
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
|
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
|
||||||
// This is subtle and surprising, but sometimes we have to bitcast
|
// This is subtle and surprising, but sometimes we have to bitcast
|
||||||
|
|
|
@ -24,6 +24,7 @@ use builder::Builder;
|
||||||
use consts;
|
use consts;
|
||||||
use declare;
|
use declare;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
use type_of::LayoutLlvmExt;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
|
@ -254,7 +255,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
|
||||||
pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
|
pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
|
||||||
let len = s.len();
|
let len = s.len();
|
||||||
let cs = consts::ptrcast(C_cstr(cx, s, false),
|
let cs = consts::ptrcast(C_cstr(cx, s, false),
|
||||||
cx.llvm_type_of(cx.tcx().mk_str()).ptr_to());
|
cx.layout_of(cx.tcx().mk_str()).llvm_type(cx).ptr_to());
|
||||||
let empty = C_array(Type::i8(cx), &[]);
|
let empty = C_array(Type::i8(cx), &[]);
|
||||||
assert_eq!(abi::FAT_PTR_ADDR, 0);
|
assert_eq!(abi::FAT_PTR_ADDR, 0);
|
||||||
assert_eq!(abi::FAT_PTR_EXTRA, 1);
|
assert_eq!(abi::FAT_PTR_EXTRA, 1);
|
||||||
|
|
|
@ -21,8 +21,9 @@ use common::{self, CrateContext, val_ty};
|
||||||
use declare;
|
use declare;
|
||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
use type_of::LayoutLlvmExt;
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::ty::layout::Align;
|
use rustc::ty::layout::{Align, LayoutOf};
|
||||||
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
||||||
let ty = common::instance_ty(ccx.tcx(), &instance);
|
let ty = common::instance_ty(ccx.tcx(), &instance);
|
||||||
let g = if let Some(id) = ccx.tcx().hir.as_local_node_id(def_id) {
|
let g = if let Some(id) = ccx.tcx().hir.as_local_node_id(def_id) {
|
||||||
|
|
||||||
let llty = ccx.llvm_type_of(ty);
|
let llty = ccx.layout_of(ty).llvm_type(ccx);
|
||||||
let (g, attrs) = match ccx.tcx().hir.get(id) {
|
let (g, attrs) = match ccx.tcx().hir.get(id) {
|
||||||
hir_map::NodeItem(&hir::Item {
|
hir_map::NodeItem(&hir::Item {
|
||||||
ref attrs, span, node: hir::ItemStatic(..), ..
|
ref attrs, span, node: hir::ItemStatic(..), ..
|
||||||
|
@ -157,7 +158,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let llty2 = match ty.sty {
|
let llty2 = match ty.sty {
|
||||||
ty::TyRawPtr(ref mt) => ccx.llvm_type_of(mt.ty),
|
ty::TyRawPtr(ref mt) => ccx.layout_of(mt.ty).llvm_type(ccx),
|
||||||
_ => {
|
_ => {
|
||||||
ccx.sess().span_fatal(span, "must have type `*const T` or `*mut T`");
|
ccx.sess().span_fatal(span, "must have type `*const T` or `*mut T`");
|
||||||
}
|
}
|
||||||
|
@ -206,7 +207,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
||||||
|
|
||||||
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
|
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
|
||||||
// FIXME(nagisa): investigate whether it can be changed into define_global
|
// FIXME(nagisa): investigate whether it can be changed into define_global
|
||||||
let g = declare::declare_global(ccx, &sym, ccx.llvm_type_of(ty));
|
let g = declare::declare_global(ccx, &sym, ccx.layout_of(ty).llvm_type(ccx));
|
||||||
// Thread-local statics in some other crate need to *always* be linked
|
// Thread-local statics in some other crate need to *always* be linked
|
||||||
// against in a thread-local fashion, so we need to be sure to apply the
|
// against in a thread-local fashion, so we need to be sure to apply the
|
||||||
// thread-local attribute locally if it was present remotely. If we
|
// thread-local attribute locally if it was present remotely. If we
|
||||||
|
@ -266,7 +267,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
|
|
||||||
let instance = Instance::mono(ccx.tcx(), def_id);
|
let instance = Instance::mono(ccx.tcx(), def_id);
|
||||||
let ty = common::instance_ty(ccx.tcx(), &instance);
|
let ty = common::instance_ty(ccx.tcx(), &instance);
|
||||||
let llty = ccx.llvm_type_of(ty);
|
let llty = ccx.layout_of(ty).llvm_type(ccx);
|
||||||
let g = if val_llty == llty {
|
let g = if val_llty == llty {
|
||||||
g
|
g
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -24,6 +24,8 @@ use monomorphize::Instance;
|
||||||
|
|
||||||
use partitioning::CodegenUnit;
|
use partitioning::CodegenUnit;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
use type_of::LayoutLlvmExt;
|
||||||
|
|
||||||
use rustc_data_structures::base_n;
|
use rustc_data_structures::base_n;
|
||||||
use rustc::middle::trans::Stats;
|
use rustc::middle::trans::Stats;
|
||||||
use rustc_data_structures::stable_hasher::StableHashingContextProvider;
|
use rustc_data_structures::stable_hasher::StableHashingContextProvider;
|
||||||
|
@ -397,7 +399,7 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
||||||
let mut str_slice_ty = Type::named_struct(&dummy_ccx, "str_slice");
|
let mut str_slice_ty = Type::named_struct(&dummy_ccx, "str_slice");
|
||||||
str_slice_ty.set_struct_body(&[
|
str_slice_ty.set_struct_body(&[
|
||||||
Type::array(&Type::i8(&dummy_ccx), 0),
|
Type::array(&Type::i8(&dummy_ccx), 0),
|
||||||
dummy_ccx.llvm_type_of(shared.tcx.mk_str()).ptr_to(),
|
dummy_ccx.layout_of(shared.tcx.mk_str()).llvm_type(&dummy_ccx).ptr_to(),
|
||||||
Type::array(&Type::i8(&dummy_ccx), 0),
|
Type::array(&Type::i8(&dummy_ccx), 0),
|
||||||
Type::isize(&dummy_ccx),
|
Type::isize(&dummy_ccx),
|
||||||
Type::array(&Type::i8(&dummy_ccx), 0)
|
Type::array(&Type::i8(&dummy_ccx), 0)
|
||||||
|
|
|
@ -21,6 +21,7 @@ use common::*;
|
||||||
use declare;
|
use declare;
|
||||||
use glue;
|
use glue;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
use type_of::LayoutLlvmExt;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::ty::layout::{HasDataLayout, LayoutOf};
|
use rustc::ty::layout::{HasDataLayout, LayoutOf};
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
@ -104,7 +105,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||||
let ret_ty = sig.output();
|
let ret_ty = sig.output();
|
||||||
let name = &*tcx.item_name(def_id);
|
let name = &*tcx.item_name(def_id);
|
||||||
|
|
||||||
let llret_ty = ccx.llvm_type_of(ret_ty);
|
let llret_ty = ccx.layout_of(ret_ty).llvm_type(ccx);
|
||||||
let result = LvalueRef::new_sized(llresult, fn_ty.ret.layout, Alignment::AbiAligned);
|
let result = LvalueRef::new_sized(llresult, fn_ty.ret.layout, Alignment::AbiAligned);
|
||||||
|
|
||||||
let simple = get_simple_intrinsic(ccx, name);
|
let simple = get_simple_intrinsic(ccx, name);
|
||||||
|
@ -243,7 +244,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMSetAlignment(load, ccx.align_of(tp_ty).abi() as u32);
|
llvm::LLVMSetAlignment(load, ccx.align_of(tp_ty).abi() as u32);
|
||||||
}
|
}
|
||||||
to_immediate(bcx, load, tp_ty)
|
to_immediate(bcx, load, ccx.layout_of(tp_ty))
|
||||||
},
|
},
|
||||||
"volatile_store" => {
|
"volatile_store" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
|
|
|
@ -662,7 +662,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
if arg.layout.ty == bcx.tcx().types.bool {
|
if arg.layout.ty == bcx.tcx().types.bool {
|
||||||
llval = bcx.load_range_assert(llval, 0, 2, llvm::False, None);
|
llval = bcx.load_range_assert(llval, 0, 2, llvm::False, None);
|
||||||
// We store bools as i8 so we need to truncate to i1.
|
// We store bools as i8 so we need to truncate to i1.
|
||||||
llval = base::to_immediate(bcx, llval, arg.layout.ty);
|
llval = base::to_immediate(bcx, llval, arg.layout);
|
||||||
} else if let Some(ty) = arg.cast {
|
} else if let Some(ty) = arg.cast {
|
||||||
llval = bcx.load(bcx.pointercast(llval, ty.llvm_type(bcx.ccx).ptr_to()),
|
llval = bcx.load(bcx.pointercast(llval, ty.llvm_type(bcx.ccx).ptr_to()),
|
||||||
(align | Alignment::Packed(arg.layout.align(bcx.ccx)))
|
(align | Alignment::Packed(arg.layout.align(bcx.ccx)))
|
||||||
|
@ -682,45 +682,37 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
args: &[ArgType<'tcx>]) {
|
args: &[ArgType<'tcx>]) {
|
||||||
let tuple = self.trans_operand(bcx, operand);
|
let tuple = self.trans_operand(bcx, operand);
|
||||||
|
|
||||||
let arg_types = match tuple.layout.ty.sty {
|
|
||||||
ty::TyTuple(ref tys, _) => tys,
|
|
||||||
_ => span_bug!(self.mir.span,
|
|
||||||
"bad final argument to \"rust-call\" fn {:?}", tuple.layout.ty)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle both by-ref and immediate tuples.
|
// Handle both by-ref and immediate tuples.
|
||||||
match tuple.val {
|
match tuple.val {
|
||||||
Ref(llval, align) => {
|
Ref(llval, align) => {
|
||||||
let tuple_ptr = LvalueRef::new_sized(llval, tuple.layout, align);
|
let tuple_ptr = LvalueRef::new_sized(llval, tuple.layout, align);
|
||||||
for n in 0..arg_types.len() {
|
for i in 0..tuple.layout.fields.count() {
|
||||||
let field_ptr = tuple_ptr.project_field(bcx, n);
|
let field_ptr = tuple_ptr.project_field(bcx, i);
|
||||||
self.trans_argument(bcx, field_ptr.load(bcx), llargs, &args[n]);
|
self.trans_argument(bcx, field_ptr.load(bcx), llargs, &args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Immediate(llval) => {
|
Immediate(llval) => {
|
||||||
for (n, &ty) in arg_types.iter().enumerate() {
|
for i in 0..tuple.layout.fields.count() {
|
||||||
let mut elem = bcx.extract_value(llval, tuple.layout.llvm_field_index(n));
|
let field = tuple.layout.field(bcx.ccx, i);
|
||||||
// Truncate bools to i1, if needed
|
let elem = bcx.extract_value(llval, tuple.layout.llvm_field_index(i));
|
||||||
elem = base::to_immediate(bcx, elem, ty);
|
|
||||||
// If the tuple is immediate, the elements are as well
|
// If the tuple is immediate, the elements are as well
|
||||||
let op = OperandRef {
|
let op = OperandRef {
|
||||||
val: Immediate(elem),
|
val: Immediate(base::to_immediate(bcx, elem, field)),
|
||||||
layout: bcx.ccx.layout_of(ty),
|
layout: field,
|
||||||
};
|
};
|
||||||
self.trans_argument(bcx, op, llargs, &args[n]);
|
self.trans_argument(bcx, op, llargs, &args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pair(a, b) => {
|
Pair(a, b) => {
|
||||||
let elems = [a, b];
|
let elems = [a, b];
|
||||||
for (n, &ty) in arg_types.iter().enumerate() {
|
for i in 0..tuple.layout.fields.count() {
|
||||||
let elem = base::to_immediate(bcx, elems[n], ty);
|
|
||||||
// Pair is always made up of immediates
|
// Pair is always made up of immediates
|
||||||
let op = OperandRef {
|
let op = OperandRef {
|
||||||
val: Immediate(elem),
|
val: Immediate(elems[i]),
|
||||||
layout: bcx.ccx.layout_of(ty),
|
layout: tuple.layout.field(bcx.ccx, i),
|
||||||
};
|
};
|
||||||
self.trans_argument(bcx, op, llargs, &args[n]);
|
self.trans_argument(bcx, op, llargs, &args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -891,7 +883,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
src: &mir::Operand<'tcx>,
|
src: &mir::Operand<'tcx>,
|
||||||
dst: LvalueRef<'tcx>) {
|
dst: LvalueRef<'tcx>) {
|
||||||
let src = self.trans_operand(bcx, src);
|
let src = self.trans_operand(bcx, src);
|
||||||
let llty = bcx.ccx.llvm_type_of(src.layout.ty);
|
let llty = src.layout.llvm_type(bcx.ccx);
|
||||||
let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
|
let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
|
||||||
let align = src.layout.align(bcx.ccx).min(dst.layout.align(bcx.ccx));
|
let align = src.layout.align(bcx.ccx).min(dst.layout.align(bcx.ccx));
|
||||||
src.val.store(bcx,
|
src.val.store(bcx,
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl<'a, 'tcx> Const<'tcx> {
|
||||||
cv: &ConstVal,
|
cv: &ConstVal,
|
||||||
ty: Ty<'tcx>)
|
ty: Ty<'tcx>)
|
||||||
-> Const<'tcx> {
|
-> Const<'tcx> {
|
||||||
let llty = ccx.llvm_type_of(ty);
|
let llty = ccx.layout_of(ty).llvm_type(ccx);
|
||||||
let val = match *cv {
|
let val = match *cv {
|
||||||
ConstVal::Float(v) => {
|
ConstVal::Float(v) => {
|
||||||
let bits = match v.ty {
|
let bits = match v.ty {
|
||||||
|
@ -139,7 +139,7 @@ impl<'a, 'tcx> Const<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_operand(&self, ccx: &CrateContext<'a, 'tcx>) -> OperandRef<'tcx> {
|
pub fn to_operand(&self, ccx: &CrateContext<'a, 'tcx>) -> OperandRef<'tcx> {
|
||||||
let llty = ccx.immediate_llvm_type_of(self.ty);
|
let llty = ccx.layout_of(self.ty).immediate_llvm_type(ccx);
|
||||||
let llvalty = val_ty(self.llval);
|
let llvalty = val_ty(self.llval);
|
||||||
|
|
||||||
let val = if llty == llvalty && common::type_is_imm_pair(ccx, self.ty) {
|
let val = if llty == llvalty && common::type_is_imm_pair(ccx, self.ty) {
|
||||||
|
@ -489,7 +489,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||||
let llelem = if iv < len as u128 {
|
let llelem = if iv < len as u128 {
|
||||||
const_get_elt(base.llval, iv as u64)
|
const_get_elt(base.llval, iv as u64)
|
||||||
} else {
|
} else {
|
||||||
C_undef(self.ccx.llvm_type_of(projected_ty))
|
C_undef(self.ccx.layout_of(projected_ty).llvm_type(self.ccx))
|
||||||
};
|
};
|
||||||
|
|
||||||
(Base::Value(llelem), ptr::null_mut())
|
(Base::Value(llelem), ptr::null_mut())
|
||||||
|
@ -543,7 +543,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||||
let elem_ty = array_ty.builtin_index().unwrap_or_else(|| {
|
let elem_ty = array_ty.builtin_index().unwrap_or_else(|| {
|
||||||
bug!("bad array type {:?}", array_ty)
|
bug!("bad array type {:?}", array_ty)
|
||||||
});
|
});
|
||||||
let llunitty = self.ccx.llvm_type_of(elem_ty);
|
let llunitty = self.ccx.layout_of(elem_ty).llvm_type(self.ccx);
|
||||||
// If the array contains enums, an LLVM array won't work.
|
// If the array contains enums, an LLVM array won't work.
|
||||||
let val = if fields.iter().all(|&f| val_ty(f) == llunitty) {
|
let val = if fields.iter().all(|&f| val_ty(f) == llunitty) {
|
||||||
C_array(llunitty, fields)
|
C_array(llunitty, fields)
|
||||||
|
@ -665,7 +665,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||||
|
|
||||||
let unsized_ty = cast_ty.builtin_deref(true, ty::NoPreference)
|
let unsized_ty = cast_ty.builtin_deref(true, ty::NoPreference)
|
||||||
.expect("consts: unsizing got non-pointer target type").ty;
|
.expect("consts: unsizing got non-pointer target type").ty;
|
||||||
let ptr_ty = self.ccx.llvm_type_of(unsized_ty).ptr_to();
|
let ptr_ty = self.ccx.layout_of(unsized_ty).llvm_type(self.ccx).ptr_to();
|
||||||
let base = consts::ptrcast(base, ptr_ty);
|
let base = consts::ptrcast(base, ptr_ty);
|
||||||
let info = base::unsized_info(self.ccx, pointee_ty,
|
let info = base::unsized_info(self.ccx, pointee_ty,
|
||||||
unsized_ty, old_info);
|
unsized_ty, old_info);
|
||||||
|
@ -681,7 +681,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||||
debug_assert!(common::type_is_immediate(self.ccx, cast_ty));
|
debug_assert!(common::type_is_immediate(self.ccx, cast_ty));
|
||||||
let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast");
|
let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast");
|
||||||
let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||||
let ll_t_out = self.ccx.immediate_llvm_type_of(cast_ty);
|
let ll_t_out = self.ccx.layout_of(cast_ty).immediate_llvm_type(self.ccx);
|
||||||
let llval = operand.llval;
|
let llval = operand.llval;
|
||||||
let signed = match self.ccx.layout_of(operand.ty).abi {
|
let signed = match self.ccx.layout_of(operand.ty).abi {
|
||||||
layout::Abi::Scalar(layout::Int(_, signed)) => signed,
|
layout::Abi::Scalar(layout::Int(_, signed)) => signed,
|
||||||
|
@ -734,7 +734,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||||
} else { // cast to thin-ptr
|
} else { // cast to thin-ptr
|
||||||
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
|
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
|
||||||
// pointer-cast of that pointer to desired pointer type.
|
// pointer-cast of that pointer to desired pointer type.
|
||||||
let llcast_ty = self.ccx.immediate_llvm_type_of(cast_ty);
|
let llcast_ty = self.ccx.layout_of(cast_ty)
|
||||||
|
.immediate_llvm_type(self.ccx);
|
||||||
consts::ptrcast(data_ptr, llcast_ty)
|
consts::ptrcast(data_ptr, llcast_ty)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1041,7 +1042,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
|
|
||||||
let result = result.unwrap_or_else(|_| {
|
let result = result.unwrap_or_else(|_| {
|
||||||
// We've errored, so we don't have to produce working code.
|
// We've errored, so we don't have to produce working code.
|
||||||
let llty = bcx.ccx.llvm_type_of(ty);
|
let llty = bcx.ccx.layout_of(ty).llvm_type(bcx.ccx);
|
||||||
Const::new(C_undef(llty), ty)
|
Const::new(C_undef(llty), ty)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1100,7 +1101,7 @@ fn trans_const_adt<'a, 'tcx>(
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
let discr_ty = l.field(ccx, 0).ty;
|
let discr_ty = l.field(ccx, 0).ty;
|
||||||
let discr = C_int(ccx.llvm_type_of(discr_ty), discr as i64);
|
let discr = C_int(ccx.layout_of(discr_ty).llvm_type(ccx), discr as i64);
|
||||||
if let layout::Abi::Scalar(_) = l.abi {
|
if let layout::Abi::Scalar(_) = l.abi {
|
||||||
Const::new(discr, t)
|
Const::new(discr, t)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1130,7 +1131,7 @@ fn trans_const_adt<'a, 'tcx>(
|
||||||
} else {
|
} else {
|
||||||
// Always use null even if it's not the `discrfield`th
|
// Always use null even if it's not the `discrfield`th
|
||||||
// field; see #8506.
|
// field; see #8506.
|
||||||
Const::new(C_null(ccx.llvm_type_of(t)), t)
|
Const::new(C_null(ccx.layout_of(t).llvm_type(ccx)), t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => bug!("trans_const_adt: cannot handle type {} repreented as {:#?}", t, l)
|
_ => bug!("trans_const_adt: cannot handle type {} repreented as {:#?}", t, l)
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
-> LvalueRef<'tcx> {
|
-> LvalueRef<'tcx> {
|
||||||
debug!("alloca({:?}: {:?})", name, layout);
|
debug!("alloca({:?}: {:?})", name, layout);
|
||||||
let tmp = bcx.alloca(
|
let tmp = bcx.alloca(
|
||||||
bcx.ccx.llvm_type_of(layout.ty), name, layout.over_align(bcx.ccx));
|
layout.llvm_type(bcx.ccx), name, layout.over_align(bcx.ccx));
|
||||||
Self::new_sized(tmp, layout, Alignment::AbiAligned)
|
Self::new_sized(tmp, layout, Alignment::AbiAligned)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
} else {
|
} else {
|
||||||
bcx.load(self.llval, self.alignment.non_abi())
|
bcx.load(self.llval, self.alignment.non_abi())
|
||||||
};
|
};
|
||||||
OperandValue::Immediate(base::to_immediate(bcx, llval, self.layout.ty))
|
OperandValue::Immediate(base::to_immediate(bcx, llval, self.layout))
|
||||||
} else {
|
} else {
|
||||||
OperandValue::Ref(self.llval, self.alignment)
|
OperandValue::Ref(self.llval, self.alignment)
|
||||||
};
|
};
|
||||||
|
@ -223,8 +223,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
bcx.struct_gep(self.llval, self.layout.llvm_field_index(ix))
|
bcx.struct_gep(self.llval, self.layout.llvm_field_index(ix))
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(offset, 0);
|
assert_eq!(offset, 0);
|
||||||
let ty = ccx.llvm_type_of(field.ty);
|
bcx.pointercast(self.llval, field.llvm_type(ccx).ptr_to())
|
||||||
bcx.pointercast(self.llval, ty.ptr_to())
|
|
||||||
},
|
},
|
||||||
llextra: if ccx.shared().type_has_metadata(field.ty) {
|
llextra: if ccx.shared().type_has_metadata(field.ty) {
|
||||||
self.llextra
|
self.llextra
|
||||||
|
@ -296,7 +295,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
let byte_ptr = bcx.gep(byte_ptr, &[offset]);
|
let byte_ptr = bcx.gep(byte_ptr, &[offset]);
|
||||||
|
|
||||||
// Finally, cast back to the type expected
|
// Finally, cast back to the type expected
|
||||||
let ll_fty = ccx.llvm_type_of(field.ty);
|
let ll_fty = field.llvm_type(ccx);
|
||||||
debug!("struct_field_ptr: Field type is {:?}", ll_fty);
|
debug!("struct_field_ptr: Field type is {:?}", ll_fty);
|
||||||
|
|
||||||
LvalueRef {
|
LvalueRef {
|
||||||
|
@ -309,7 +308,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
|
|
||||||
/// Obtain the actual discriminant of a value.
|
/// Obtain the actual discriminant of a value.
|
||||||
pub fn trans_get_discr(self, bcx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
|
pub fn trans_get_discr(self, bcx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
|
||||||
let cast_to = bcx.ccx.immediate_llvm_type_of(cast_to);
|
let cast_to = bcx.ccx.layout_of(cast_to).immediate_llvm_type(bcx.ccx);
|
||||||
match *self.layout.layout {
|
match *self.layout.layout {
|
||||||
layout::Layout::Univariant { .. } |
|
layout::Layout::Univariant { .. } |
|
||||||
layout::Layout::UntaggedUnion { .. } => return C_uint(cast_to, 0),
|
layout::Layout::UntaggedUnion { .. } => return C_uint(cast_to, 0),
|
||||||
|
@ -357,7 +356,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
}
|
}
|
||||||
layout::Layout::NullablePointer { nndiscr, .. } => {
|
layout::Layout::NullablePointer { nndiscr, .. } => {
|
||||||
let cmp = if nndiscr == 0 { llvm::IntEQ } else { llvm::IntNE };
|
let cmp = if nndiscr == 0 { llvm::IntEQ } else { llvm::IntNE };
|
||||||
let zero = C_null(bcx.ccx.llvm_type_of(discr.layout.ty));
|
let zero = C_null(discr.layout.llvm_type(bcx.ccx));
|
||||||
bcx.intcast(bcx.icmp(cmp, lldiscr, zero), cast_to, false)
|
bcx.intcast(bcx.icmp(cmp, lldiscr, zero), cast_to, false)
|
||||||
}
|
}
|
||||||
_ => bug!("{} is not an enum", self.layout.ty)
|
_ => bug!("{} is not an enum", self.layout.ty)
|
||||||
|
@ -373,7 +372,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
match *self.layout.layout {
|
match *self.layout.layout {
|
||||||
layout::Layout::General { .. } => {
|
layout::Layout::General { .. } => {
|
||||||
let ptr = self.project_field(bcx, 0);
|
let ptr = self.project_field(bcx, 0);
|
||||||
bcx.store(C_int(bcx.ccx.llvm_type_of(ptr.layout.ty), to as i64),
|
bcx.store(C_int(ptr.layout.llvm_type(bcx.ccx), to as i64),
|
||||||
ptr.llval, ptr.alignment.non_abi());
|
ptr.llval, ptr.alignment.non_abi());
|
||||||
}
|
}
|
||||||
layout::Layout::NullablePointer { nndiscr, .. } => {
|
layout::Layout::NullablePointer { nndiscr, .. } => {
|
||||||
|
@ -394,7 +393,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
base::call_memset(bcx, llptr, fill_byte, size, align, false);
|
base::call_memset(bcx, llptr, fill_byte, size, align, false);
|
||||||
} else {
|
} else {
|
||||||
let ptr = self.project_field(bcx, 0);
|
let ptr = self.project_field(bcx, 0);
|
||||||
bcx.store(C_null(bcx.ccx.llvm_type_of(ptr.layout.ty)),
|
bcx.store(C_null(ptr.layout.llvm_type(bcx.ccx)),
|
||||||
ptr.llval, ptr.alignment.non_abi());
|
ptr.llval, ptr.alignment.non_abi());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -523,7 +522,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
// Cast the lvalue pointer type to the new
|
// Cast the lvalue pointer type to the new
|
||||||
// array or slice type (*[%_; new_len]).
|
// array or slice type (*[%_; new_len]).
|
||||||
subslice.llval = bcx.pointercast(subslice.llval,
|
subslice.llval = bcx.pointercast(subslice.llval,
|
||||||
bcx.ccx.llvm_type_of(subslice.layout.ty).ptr_to());
|
subslice.layout.llvm_type(bcx.ccx).ptr_to());
|
||||||
|
|
||||||
subslice
|
subslice
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ use common::{self, CrateContext, Funclet};
|
||||||
use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
|
use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
|
||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
use abi::{ArgAttribute, FnType};
|
use abi::{ArgAttribute, FnType};
|
||||||
use type_of;
|
use type_of::{self, LayoutLlvmExt};
|
||||||
|
|
||||||
use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
|
use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
|
@ -465,7 +465,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||||
ty::TyAdt(def, _) if def.is_box() => arg.layout.ty.boxed_ty(),
|
ty::TyAdt(def, _) if def.is_box() => arg.layout.ty.boxed_ty(),
|
||||||
_ => bug!()
|
_ => bug!()
|
||||||
};
|
};
|
||||||
let data_llty = bcx.ccx.llvm_type_of(pointee);
|
let data_llty = bcx.ccx.layout_of(pointee).llvm_type(bcx.ccx);
|
||||||
let meta_llty = type_of::unsized_info_ty(bcx.ccx, pointee);
|
let meta_llty = type_of::unsized_info_ty(bcx.ccx, pointee);
|
||||||
|
|
||||||
a = bcx.pointercast(a, data_llty.ptr_to());
|
a = bcx.pointercast(a, data_llty.ptr_to());
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||||
pub fn new_zst(ccx: &CrateContext<'a, 'tcx>,
|
pub fn new_zst(ccx: &CrateContext<'a, 'tcx>,
|
||||||
layout: FullLayout<'tcx>) -> OperandRef<'tcx> {
|
layout: FullLayout<'tcx>) -> OperandRef<'tcx> {
|
||||||
assert!(layout.is_zst());
|
assert!(layout.is_zst());
|
||||||
let llty = ccx.llvm_type_of(layout.ty);
|
let llty = layout.llvm_type(ccx);
|
||||||
// FIXME(eddyb) ZSTs should always be immediate, not pairs.
|
// FIXME(eddyb) ZSTs should always be immediate, not pairs.
|
||||||
// This hack only exists to unpack a constant undef pair.
|
// This hack only exists to unpack a constant undef pair.
|
||||||
Const::new(C_undef(llty), layout.ty).to_operand(ccx)
|
Const::new(C_undef(llty), layout.ty).to_operand(ccx)
|
||||||
|
@ -119,7 +119,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||||
/// Immediate aggregate with the two values.
|
/// Immediate aggregate with the two values.
|
||||||
pub fn pack_if_pair(mut self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
|
pub fn pack_if_pair(mut self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
|
||||||
if let OperandValue::Pair(a, b) = self.val {
|
if let OperandValue::Pair(a, b) = self.val {
|
||||||
let llty = bcx.ccx.llvm_type_of(self.layout.ty);
|
let llty = self.layout.llvm_type(bcx.ccx);
|
||||||
debug!("Operand::pack_if_pair: packing {:?} into {:?}", self, llty);
|
debug!("Operand::pack_if_pair: packing {:?} into {:?}", self, llty);
|
||||||
// Reconstruct the immediate aggregate.
|
// Reconstruct the immediate aggregate.
|
||||||
let mut llpair = C_undef(llty);
|
let mut llpair = C_undef(llty);
|
||||||
|
@ -142,10 +142,10 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||||
debug!("Operand::unpack_if_pair: unpacking {:?}", self);
|
debug!("Operand::unpack_if_pair: unpacking {:?}", self);
|
||||||
|
|
||||||
let a = bcx.extract_value(llval, self.layout.llvm_field_index(0));
|
let a = bcx.extract_value(llval, self.layout.llvm_field_index(0));
|
||||||
let a = base::to_immediate(bcx, a, self.layout.field(bcx.ccx, 0).ty);
|
let a = base::to_immediate(bcx, a, self.layout.field(bcx.ccx, 0));
|
||||||
|
|
||||||
let b = bcx.extract_value(llval, self.layout.llvm_field_index(1));
|
let b = bcx.extract_value(llval, self.layout.llvm_field_index(1));
|
||||||
let b = base::to_immediate(bcx, b, self.layout.field(bcx.ccx, 1).ty);
|
let b = base::to_immediate(bcx, b, self.layout.field(bcx.ccx, 1));
|
||||||
|
|
||||||
self.val = OperandValue::Pair(a, b);
|
self.val = OperandValue::Pair(a, b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ use common::{C_bool, C_u8, C_i32, C_u32, C_u64, C_null, C_usize, C_uint, C_big_i
|
||||||
use consts;
|
use consts;
|
||||||
use monomorphize;
|
use monomorphize;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use type_of;
|
use type_of::{self, LayoutLlvmExt};
|
||||||
use value::Value;
|
use value::Value;
|
||||||
|
|
||||||
use super::{MirContext, LocalRef};
|
use super::{MirContext, LocalRef};
|
||||||
|
@ -259,7 +259,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
} else { // cast to thin-ptr
|
} else { // cast to thin-ptr
|
||||||
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
|
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
|
||||||
// pointer-cast of that pointer to desired pointer type.
|
// pointer-cast of that pointer to desired pointer type.
|
||||||
let llcast_ty = bcx.ccx.immediate_llvm_type_of(cast.ty);
|
let llcast_ty = cast.immediate_llvm_type(bcx.ccx);
|
||||||
let llval = bcx.pointercast(data_ptr, llcast_ty);
|
let llval = bcx.pointercast(data_ptr, llcast_ty);
|
||||||
OperandValue::Immediate(llval)
|
OperandValue::Immediate(llval)
|
||||||
}
|
}
|
||||||
|
@ -272,8 +272,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
let r_t_in = CastTy::from_ty(operand.layout.ty)
|
let r_t_in = CastTy::from_ty(operand.layout.ty)
|
||||||
.expect("bad input type for cast");
|
.expect("bad input type for cast");
|
||||||
let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast");
|
let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast");
|
||||||
let ll_t_in = bcx.ccx.immediate_llvm_type_of(operand.layout.ty);
|
let ll_t_in = operand.layout.immediate_llvm_type(bcx.ccx);
|
||||||
let ll_t_out = bcx.ccx.immediate_llvm_type_of(cast.ty);
|
let ll_t_out = cast.immediate_llvm_type(bcx.ccx);
|
||||||
let llval = operand.immediate();
|
let llval = operand.immediate();
|
||||||
|
|
||||||
if let Layout::General { ref discr_range, .. } = *operand.layout.layout {
|
if let Layout::General { ref discr_range, .. } = *operand.layout.layout {
|
||||||
|
@ -453,7 +453,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
let llsize = C_usize(bcx.ccx, size.bytes());
|
let llsize = C_usize(bcx.ccx, size.bytes());
|
||||||
let llalign = C_usize(bcx.ccx, align.abi());
|
let llalign = C_usize(bcx.ccx, align.abi());
|
||||||
let box_layout = bcx.ccx.layout_of(bcx.tcx().mk_box(content_ty));
|
let box_layout = bcx.ccx.layout_of(bcx.tcx().mk_box(content_ty));
|
||||||
let llty_ptr = bcx.ccx.llvm_type_of(box_layout.ty);
|
let llty_ptr = box_layout.llvm_type(bcx.ccx);
|
||||||
|
|
||||||
// Allocate space:
|
// Allocate space:
|
||||||
let def_id = match bcx.tcx().lang_items().require(ExchangeMallocFnLangItem) {
|
let def_id = match bcx.tcx().lang_items().require(ExchangeMallocFnLangItem) {
|
||||||
|
|
|
@ -23,9 +23,11 @@ use common;
|
||||||
use declare;
|
use declare;
|
||||||
use llvm;
|
use llvm;
|
||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
|
use type_of::LayoutLlvmExt;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::middle::trans::{Linkage, Visibility};
|
use rustc::middle::trans::{Linkage, Visibility};
|
||||||
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
||||||
|
use rustc::ty::layout::LayoutOf;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
@ -172,7 +174,7 @@ fn predefine_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
let def_id = ccx.tcx().hir.local_def_id(node_id);
|
let def_id = ccx.tcx().hir.local_def_id(node_id);
|
||||||
let instance = Instance::mono(ccx.tcx(), def_id);
|
let instance = Instance::mono(ccx.tcx(), def_id);
|
||||||
let ty = common::instance_ty(ccx.tcx(), &instance);
|
let ty = common::instance_ty(ccx.tcx(), &instance);
|
||||||
let llty = ccx.llvm_type_of(ty);
|
let llty = ccx.layout_of(ty).llvm_type(ccx);
|
||||||
|
|
||||||
let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| {
|
let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| {
|
||||||
ccx.sess().span_fatal(ccx.tcx().hir.span(node_id),
|
ccx.sess().span_fatal(ccx.tcx().hir.span(node_id),
|
||||||
|
|
|
@ -21,10 +21,10 @@ pub fn fat_ptr_base_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) ->
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyRef(_, ty::TypeAndMut { ty: t, .. }) |
|
ty::TyRef(_, ty::TypeAndMut { ty: t, .. }) |
|
||||||
ty::TyRawPtr(ty::TypeAndMut { ty: t, .. }) if ccx.shared().type_has_metadata(t) => {
|
ty::TyRawPtr(ty::TypeAndMut { ty: t, .. }) if ccx.shared().type_has_metadata(t) => {
|
||||||
ccx.llvm_type_of(t).ptr_to()
|
ccx.layout_of(t).llvm_type(ccx).ptr_to()
|
||||||
}
|
}
|
||||||
ty::TyAdt(def, _) if def.is_box() => {
|
ty::TyAdt(def, _) if def.is_box() => {
|
||||||
ccx.llvm_type_of(ty.boxed_ty()).ptr_to()
|
ccx.layout_of(ty.boxed_ty()).llvm_type(ccx).ptr_to()
|
||||||
}
|
}
|
||||||
_ => bug!("expected fat ptr ty but got {:?}", ty)
|
_ => bug!("expected fat ptr ty but got {:?}", ty)
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
// unsized).
|
// unsized).
|
||||||
cx.str_slice_type()
|
cx.str_slice_type()
|
||||||
} else {
|
} else {
|
||||||
let ptr_ty = cx.llvm_type_of(ty).ptr_to();
|
let ptr_ty = cx.layout_of(ty).llvm_type(cx).ptr_to();
|
||||||
let info_ty = unsized_info_ty(cx, ty);
|
let info_ty = unsized_info_ty(cx, ty);
|
||||||
Type::struct_(cx, &[
|
Type::struct_(cx, &[
|
||||||
Type::array(&Type::i8(cx), 0),
|
Type::array(&Type::i8(cx), 0),
|
||||||
|
@ -64,7 +64,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
], false)
|
], false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cx.llvm_type_of(ty).ptr_to()
|
cx.layout_of(ty).llvm_type(cx).ptr_to()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
|
@ -89,13 +89,15 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
layout::Int(i, _) => Type::from_integer(cx, i),
|
layout::Int(i, _) => Type::from_integer(cx, i),
|
||||||
layout::F32 => Type::f32(cx),
|
layout::F32 => Type::f32(cx),
|
||||||
layout::F64 => Type::f64(cx),
|
layout::F64 => Type::f64(cx),
|
||||||
layout::Pointer => cx.llvm_type_of(layout::Pointer.to_ty(cx.tcx()))
|
layout::Pointer => {
|
||||||
|
cx.layout_of(layout::Pointer.to_ty(cx.tcx())).llvm_type(cx)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return llty;
|
return llty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let layout::Abi::Vector { .. } = layout.abi {
|
if let layout::Abi::Vector { .. } = layout.abi {
|
||||||
return Type::vector(&cx.llvm_type_of(layout.field(cx, 0).ty),
|
return Type::vector(&layout.field(cx, 0).llvm_type(cx),
|
||||||
layout.fields.count() as u64);
|
layout.fields.count() as u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +127,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layout::FieldPlacement::Array { count, .. } => {
|
layout::FieldPlacement::Array { count, .. } => {
|
||||||
Type::array(&cx.llvm_type_of(layout.field(cx, 0).ty), count)
|
Type::array(&layout.field(cx, 0).llvm_type(cx), count)
|
||||||
}
|
}
|
||||||
layout::FieldPlacement::Arbitrary { .. } => {
|
layout::FieldPlacement::Arbitrary { .. } => {
|
||||||
match name {
|
match name {
|
||||||
|
@ -161,8 +163,7 @@ pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
result.push(Type::array(&Type::i8(cx), padding.bytes()));
|
result.push(Type::array(&Type::i8(cx), padding.bytes()));
|
||||||
debug!(" padding before: {:?}", padding);
|
debug!(" padding before: {:?}", padding);
|
||||||
|
|
||||||
let llty = cx.llvm_type_of(field.ty);
|
result.push(field.llvm_type(cx));
|
||||||
result.push(llty);
|
|
||||||
|
|
||||||
if layout.is_packed() {
|
if layout.is_packed() {
|
||||||
assert_eq!(padding.bytes(), 0);
|
assert_eq!(padding.bytes(), 0);
|
||||||
|
@ -206,12 +207,16 @@ impl<'a, 'tcx> CrateContext<'a, 'tcx> {
|
||||||
let layout = self.layout_of(ty);
|
let layout = self.layout_of(ty);
|
||||||
(layout.size(self), layout.align(self))
|
(layout.size(self), layout.align(self))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns alignment if it is different than the primitive alignment.
|
pub trait LayoutLlvmExt<'tcx> {
|
||||||
pub fn over_align_of(&self, ty: Ty<'tcx>) -> Option<Align> {
|
fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type;
|
||||||
self.layout_of(ty).over_align(self)
|
fn immediate_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type;
|
||||||
}
|
fn over_align(&self, ccx: &CrateContext) -> Option<Align>;
|
||||||
|
fn llvm_field_index(&self, index: usize) -> u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> LayoutLlvmExt<'tcx> for FullLayout<'tcx> {
|
||||||
/// Get the LLVM type corresponding to a Rust type, i.e. `rustc::ty::Ty`.
|
/// Get the LLVM type corresponding to a Rust type, i.e. `rustc::ty::Ty`.
|
||||||
/// The pointee type of the pointer in `LvalueRef` is always this type.
|
/// The pointee type of the pointer in `LvalueRef` is always this type.
|
||||||
/// For sized types, it is also the right LLVM type for an `alloca`
|
/// For sized types, it is also the right LLVM type for an `alloca`
|
||||||
|
@ -223,56 +228,45 @@ impl<'a, 'tcx> CrateContext<'a, 'tcx> {
|
||||||
/// with the inner-most trailing unsized field using the "minimal unit"
|
/// with the inner-most trailing unsized field using the "minimal unit"
|
||||||
/// of that field's type - this is useful for taking the address of
|
/// of that field's type - this is useful for taking the address of
|
||||||
/// that field and ensuring the struct has the right alignment.
|
/// that field and ensuring the struct has the right alignment.
|
||||||
pub fn llvm_type_of(&self, ty: Ty<'tcx>) -> Type {
|
fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
|
||||||
// Check the cache.
|
// Check the cache.
|
||||||
if let Some(&llty) = self.lltypes().borrow().get(&ty) {
|
if let Some(&llty) = ccx.lltypes().borrow().get(&self.ty) {
|
||||||
return llty;
|
return llty;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("type_of {:?}", ty);
|
debug!("llvm_type({:#?})", self);
|
||||||
|
|
||||||
assert!(!ty.has_escaping_regions(), "{:?} has escaping regions", ty);
|
assert!(!self.ty.has_escaping_regions(), "{:?} has escaping regions", self.ty);
|
||||||
|
|
||||||
// Make sure lifetimes are erased, to avoid generating distinct LLVM
|
// Make sure lifetimes are erased, to avoid generating distinct LLVM
|
||||||
// types for Rust types that only differ in the choice of lifetimes.
|
// types for Rust types that only differ in the choice of lifetimes.
|
||||||
let normal_ty = self.tcx().erase_regions(&ty);
|
let normal_ty = ccx.tcx().erase_regions(&self.ty);
|
||||||
|
|
||||||
if ty != normal_ty {
|
|
||||||
let llty = self.llvm_type_of(normal_ty);
|
|
||||||
debug!("--> normalized {:?} to {:?} llty={:?}", ty, normal_ty, llty);
|
|
||||||
self.lltypes().borrow_mut().insert(ty, llty);
|
|
||||||
return llty;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut defer = None;
|
let mut defer = None;
|
||||||
let llty = uncached_llvm_type(self, ty, &mut defer);
|
let llty = if self.ty != normal_ty {
|
||||||
|
ccx.layout_of(normal_ty).llvm_type(ccx)
|
||||||
|
} else {
|
||||||
|
uncached_llvm_type(ccx, self.ty, &mut defer)
|
||||||
|
};
|
||||||
|
debug!("--> mapped {:#?} to llty={:?}", self, llty);
|
||||||
|
|
||||||
debug!("--> mapped ty={:?} to llty={:?}", ty, llty);
|
ccx.lltypes().borrow_mut().insert(self.ty, llty);
|
||||||
|
|
||||||
self.lltypes().borrow_mut().insert(ty, llty);
|
|
||||||
|
|
||||||
if let Some((mut llty, layout)) = defer {
|
if let Some((mut llty, layout)) = defer {
|
||||||
llty.set_struct_body(&struct_llfields(self, layout), layout.is_packed())
|
llty.set_struct_body(&struct_llfields(ccx, layout), layout.is_packed())
|
||||||
}
|
}
|
||||||
|
|
||||||
llty
|
llty
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn immediate_llvm_type_of(&self, ty: Ty<'tcx>) -> Type {
|
fn immediate_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
|
||||||
if ty.is_bool() {
|
if let layout::Abi::Scalar(layout::Int(layout::I1, _)) = self.abi {
|
||||||
Type::i1(self)
|
Type::i1(ccx)
|
||||||
} else {
|
} else {
|
||||||
self.llvm_type_of(ty)
|
self.llvm_type(ccx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub trait LayoutLlvmExt {
|
|
||||||
fn over_align(&self, ccx: &CrateContext) -> Option<Align>;
|
|
||||||
fn llvm_field_index(&self, index: usize) -> u64;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> LayoutLlvmExt for FullLayout<'tcx> {
|
|
||||||
fn over_align(&self, ccx: &CrateContext) -> Option<Align> {
|
fn over_align(&self, ccx: &CrateContext) -> Option<Align> {
|
||||||
let align = self.align(ccx);
|
let align = self.align(ccx);
|
||||||
let primitive_align = self.primitive_align(ccx);
|
let primitive_align = self.primitive_align(ccx);
|
||||||
|
|
Loading…
Reference in New Issue