1
Fork 0

Generalized base::unsized_info

This commit is contained in:
Denis Merigoux 2018-09-13 14:58:19 +02:00 committed by Eduard-Mihai Burtescu
parent 484e07c231
commit 034f69753b
26 changed files with 338 additions and 287 deletions

View file

@ -55,7 +55,6 @@ use builder::{Builder, MemFlags};
use callee; use callee;
use rustc_mir::monomorphize::item::DefPathBasedNames; use rustc_mir::monomorphize::item::DefPathBasedNames;
use common::{self, IntPredicate, RealPredicate, TypeKind}; use common::{self, IntPredicate, RealPredicate, TypeKind};
use consts;
use context::CodegenCx; use context::CodegenCx;
use debuginfo; use debuginfo;
use declare; use declare;
@ -188,16 +187,16 @@ pub fn compare_simd_types<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
/// The `old_info` argument is a bit funny. It is intended for use /// The `old_info` argument is a bit funny. It is intended for use
/// in an upcast, where the new vtable for an object will be derived /// in an upcast, where the new vtable for an object will be derived
/// from the old one. /// from the old one.
pub fn unsized_info( pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &CodegenCx<'ll, 'tcx>, cx: &Cx,
source: Ty<'tcx>, source: Ty<'tcx>,
target: Ty<'tcx>, target: Ty<'tcx>,
old_info: Option<&'ll Value>, old_info: Option<Cx::Value>,
) -> &'ll Value { ) -> Cx::Value {
let (source, target) = cx.tcx.struct_lockstep_tails(source, target); let (source, target) = cx.tcx().struct_lockstep_tails(source, target);
match (&source.sty, &target.sty) { match (&source.sty, &target.sty) {
(&ty::Array(_, len), &ty::Slice(_)) => { (&ty::Array(_, len), &ty::Slice(_)) => {
cx.const_usize(len.unwrap_usize(cx.tcx)) cx.const_usize(len.unwrap_usize(cx.tcx()))
} }
(&ty::Dynamic(..), &ty::Dynamic(..)) => { (&ty::Dynamic(..), &ty::Dynamic(..)) => {
// For now, upcasts are limited to changes in marker // For now, upcasts are limited to changes in marker
@ -206,10 +205,10 @@ pub fn unsized_info(
old_info.expect("unsized_info: missing old info for trait upcast") old_info.expect("unsized_info: missing old info for trait upcast")
} }
(_, &ty::Dynamic(ref data, ..)) => { (_, &ty::Dynamic(ref data, ..)) => {
let vtable_ptr = cx.layout_of(cx.tcx.mk_mut_ptr(target)) let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target))
.field(cx, abi::FAT_PTR_EXTRA); .field(cx, abi::FAT_PTR_EXTRA);
consts::ptrcast(meth::get_vtable(cx, source, data.principal()), cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()),
vtable_ptr.llvm_type(cx)) cx.backend_type(vtable_ptr))
} }
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}",
source, source,

View file

@ -15,8 +15,8 @@ use context::CodegenCx;
use type_::Type; use type_::Type;
use value::Value; use value::Value;
use libc::{c_uint, c_char}; use libc::{c_uint, c_char};
use rustc::ty::TyCtxt; use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::{Align, Size}; use rustc::ty::layout::{Align, Size, TyLayout};
use rustc::session::{config, Session}; use rustc::session::{config, Session};
use rustc_data_structures::small_c_str::SmallCStr; use rustc_data_structures::small_c_str::SmallCStr;
use interfaces::*; use interfaces::*;
@ -56,7 +56,36 @@ bitflags! {
} }
} }
impl HasCodegen for Builder<'a, 'll, 'tcx> { impl BackendTypes for Builder<'_, 'll, '_> {
type Value = &'ll Value;
type BasicBlock = &'ll BasicBlock;
type Type = &'ll Type;
type Context = &'ll llvm::Context;
}
impl ty::layout::HasDataLayout for Builder<'_, '_, '_> {
fn data_layout(&self) -> &ty::layout::TargetDataLayout {
self.cx.data_layout()
}
}
impl ty::layout::HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> {
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.cx.tcx
}
}
impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> {
type Ty = Ty<'tcx>;
type TyLayout = TyLayout<'tcx>;
fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
self.cx.layout_of(ty)
}
}
impl HasCodegen<'tcx> for Builder<'_, 'll, 'tcx> {
type CodegenCx = CodegenCx<'ll, 'tcx>; type CodegenCx = CodegenCx<'ll, 'tcx>;
} }
@ -98,10 +127,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
self.cx.sess() self.cx.sess()
} }
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.cx.tcx
}
fn llfn(&self) -> &'ll Value { fn llfn(&self) -> &'ll Value {
unsafe { unsafe {
llvm::LLVMGetBasicBlockParent(self.llbb()) llvm::LLVMGetBasicBlockParent(self.llbb())

View file

@ -22,7 +22,7 @@ use llvm;
use monomorphize::Instance; use monomorphize::Instance;
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;
use value::Value; use value::Value;
use interfaces::BaseTypeMethods; use interfaces::*;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::ty::{self, TypeFoldable}; use rustc::ty::{self, TypeFoldable};
@ -206,15 +206,16 @@ pub fn get_fn(
llfn llfn
} }
pub fn resolve_and_get_fn( pub fn resolve_and_get_fn<'tcx,
cx: &CodegenCx<'ll, 'tcx>, Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
>(
cx: &Cx,
def_id: DefId, def_id: DefId,
substs: &'tcx Substs<'tcx>, substs: &'tcx Substs<'tcx>,
) -> &'ll Value { ) -> Cx::Value {
get_fn( cx.get_fn(
cx,
ty::Instance::resolve( ty::Instance::resolve(
cx.tcx, cx.tcx(),
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
def_id, def_id,
substs substs
@ -222,15 +223,16 @@ pub fn resolve_and_get_fn(
) )
} }
pub fn resolve_and_get_fn_for_vtable( pub fn resolve_and_get_fn_for_vtable<'tcx,
cx: &CodegenCx<'ll, 'tcx>, Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
>(
cx: &Cx,
def_id: DefId, def_id: DefId,
substs: &'tcx Substs<'tcx>, substs: &'tcx Substs<'tcx>,
) -> &'ll Value { ) -> Cx::Value {
get_fn( cx.get_fn(
cx,
ty::Instance::resolve_for_vtable( ty::Instance::resolve_for_vtable(
cx.tcx, cx.tcx(),
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
def_id, def_id,
substs substs

View file

@ -23,12 +23,11 @@ use declare;
use type_::Type; use type_::Type;
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;
use value::Value; use value::Value;
use interfaces::{Backend, ConstMethods, BaseTypeMethods}; use interfaces::{BackendTypes, BuilderMethods, ConstMethods, BaseTypeMethods};
use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::{HasDataLayout, LayoutOf}; use rustc::ty::layout::{HasDataLayout, LayoutOf};
use rustc::hir; use rustc::hir;
use interfaces::BuilderMethods;
use libc::{c_uint, c_char}; use libc::{c_uint, c_char};
@ -213,15 +212,14 @@ impl Funclet<'ll> {
} }
} }
impl Backend for CodegenCx<'ll, 'tcx> { impl BackendTypes for CodegenCx<'ll, 'tcx> {
type Value = &'ll Value; type Value = &'ll Value;
type BasicBlock = &'ll BasicBlock; type BasicBlock = &'ll BasicBlock;
type Type = &'ll Type; type Type = &'ll Type;
type Context = &'ll llvm::Context; type Context = &'ll llvm::Context;
} }
impl<'ll, 'tcx: 'll> ConstMethods for CodegenCx<'ll, 'tcx> { impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// LLVM constant constructors. // LLVM constant constructors.
fn const_null(&self, t: &'ll Type) -> &'ll Value { fn const_null(&self, t: &'ll Type) -> &'ll Value {
unsafe { unsafe {
@ -319,7 +317,7 @@ impl<'ll, 'tcx: 'll> ConstMethods for CodegenCx<'ll, 'tcx> {
fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value { fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
let len = s.len(); let len = s.len();
let cs = consts::ptrcast(self.const_cstr(s, false), let cs = consts::ptrcast(self.const_cstr(s, false),
self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(&self))); self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
self.const_fat_ptr(cs, self.const_usize(len as u64)) self.const_fat_ptr(cs, self.const_usize(len as u64))
} }

View file

@ -201,7 +201,7 @@ impl StaticMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let g = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { let g = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
let llty = self.layout_of(ty).llvm_type(&self); let llty = self.layout_of(ty).llvm_type(self);
let (g, attrs) = match self.tcx.hir.get(id) { let (g, attrs) = match self.tcx.hir.get(id) {
Node::Item(&hir::Item { Node::Item(&hir::Item {
ref attrs, span, node: hir::ItemKind::Static(..), .. ref attrs, span, node: hir::ItemKind::Static(..), ..
@ -329,7 +329,7 @@ impl StaticMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let instance = Instance::mono(self.tcx, def_id); let instance = Instance::mono(self.tcx, def_id);
let ty = instance.ty(self.tcx); let ty = instance.ty(self.tcx);
let llty = self.layout_of(ty).llvm_type(&self); let llty = self.layout_of(ty).llvm_type(self);
let g = if val_llty == llty { let g = if val_llty == llty {
g g
} else { } else {

View file

@ -23,7 +23,7 @@ use value::Value;
use monomorphize::partitioning::CodegenUnit; use monomorphize::partitioning::CodegenUnit;
use type_::Type; use type_::Type;
use type_of::PointeeInfo; use type_of::PointeeInfo;
use interfaces::{BaseTypeMethods, DerivedTypeMethods, IntrinsicDeclarationMethods}; use interfaces::*;
use rustc_data_structures::base_n; use rustc_data_structures::base_n;
use rustc_data_structures::small_c_str::SmallCStr; use rustc_data_structures::small_c_str::SmallCStr;
@ -322,7 +322,18 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
} }
} }
impl IntrinsicDeclarationMethods for CodegenCx<'b, 'tcx> { impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn vtables(&self) -> &RefCell<FxHashMap<(Ty<'tcx>,
ty::PolyExistentialTraitRef<'tcx>), &'ll Value>>
{
&self.vtables
}
fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
callee::get_fn(&&self,instance)
}
}
impl IntrinsicDeclarationMethods<'tcx> for CodegenCx<'b, 'tcx> {
fn get_intrinsic(&self, key: &str) -> &'b Value { fn get_intrinsic(&self, key: &str) -> &'b Value {
if let Some(v) = self.intrinsics.borrow().get(key).cloned() { if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
return v; return v;

View file

@ -17,6 +17,7 @@ use super::utils::{debug_context, DIB, span_start,
use super::namespace::mangled_name_of_instance; use super::namespace::mangled_name_of_instance;
use super::type_names::compute_debuginfo_type_name; use super::type_names::compute_debuginfo_type_name;
use super::{CrateDebugContext}; use super::{CrateDebugContext};
use interfaces::*;
use abi; use abi;
use interfaces::ConstMethods; use interfaces::ConstMethods;
use value::Value; use value::Value;
@ -1983,26 +1984,27 @@ pub fn extend_scope_to_file(
} }
} }
/// Creates debug information for the given vtable, which is for the impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
/// given type. /// Creates debug information for the given vtable, which is for the
/// /// given type.
/// Adds the created metadata nodes directly to the crate's IR. ///
pub fn create_vtable_metadata( /// Adds the created metadata nodes directly to the crate's IR.
cx: &CodegenCx<'ll, 'tcx>, fn create_vtable_metadata(
&self,
ty: ty::Ty<'tcx>, ty: ty::Ty<'tcx>,
vtable: &'ll Value, vtable: &'ll Value,
) { ) {
if cx.dbg_cx.is_none() { if self.dbg_cx.is_none() {
return; return;
} }
let type_metadata = type_metadata(cx, ty, syntax_pos::DUMMY_SP); let type_metadata = type_metadata(&self, ty, syntax_pos::DUMMY_SP);
unsafe { unsafe {
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions // pointer will lead to hard to trace and debug LLVM assertions
// later on in llvm/lib/IR/Value.cpp. // later on in llvm/lib/IR/Value.cpp.
let empty_array = create_DIArray(DIB(cx), &[]); let empty_array = create_DIArray(DIB(&self), &[]);
let name = const_cstr!("vtable"); let name = const_cstr!("vtable");
@ -2010,13 +2012,13 @@ pub fn create_vtable_metadata(
// here, because each vtable will refer to a unique containing // here, because each vtable will refer to a unique containing
// type. // type.
let vtable_type = llvm::LLVMRustDIBuilderCreateStructType( let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
DIB(cx), DIB(&self),
NO_SCOPE_METADATA, NO_SCOPE_METADATA,
name.as_ptr(), name.as_ptr(),
unknown_file_metadata(cx), unknown_file_metadata(&self),
UNKNOWN_LINE_NUMBER, UNKNOWN_LINE_NUMBER,
Size::ZERO.bits(), Size::ZERO.bits(),
cx.tcx.data_layout.pointer_align.abi_bits() as u32, self.tcx.data_layout.pointer_align.abi_bits() as u32,
DIFlags::FlagArtificial, DIFlags::FlagArtificial,
None, None,
empty_array, empty_array,
@ -2025,11 +2027,11 @@ pub fn create_vtable_metadata(
name.as_ptr() name.as_ptr()
); );
llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx), llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(&self),
NO_SCOPE_METADATA, NO_SCOPE_METADATA,
name.as_ptr(), name.as_ptr(),
ptr::null(), ptr::null(),
unknown_file_metadata(cx), unknown_file_metadata(&self),
UNKNOWN_LINE_NUMBER, UNKNOWN_LINE_NUMBER,
vtable_type, vtable_type,
true, true,
@ -2037,4 +2039,5 @@ pub fn create_vtable_metadata(
None, None,
0); 0);
} }
}
} }

View file

@ -58,7 +58,6 @@ mod source_loc;
pub use self::create_scope_map::{create_mir_scopes, MirDebugScope}; pub use self::create_scope_map::{create_mir_scopes, MirDebugScope};
pub use self::source_loc::start_emitting_source_locations; pub use self::source_loc::start_emitting_source_locations;
pub use self::metadata::create_global_var_metadata; pub use self::metadata::create_global_var_metadata;
pub use self::metadata::create_vtable_metadata;
pub use self::metadata::extend_scope_to_file; pub use self::metadata::extend_scope_to_file;
pub use self::source_loc::set_source_location; pub use self::source_loc::set_source_location;

View file

@ -17,7 +17,7 @@ use std;
use builder::Builder; use builder::Builder;
use common::*; use common::*;
use meth; use meth;
use rustc::ty::layout::LayoutOf; use rustc::ty::layout::{LayoutOf, HasTyCtxt};
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use value::Value; use value::Value;
use interfaces::{BuilderMethods, ConstMethods}; use interfaces::{BuilderMethods, ConstMethods};

View file

@ -8,11 +8,22 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout};
use rustc::ty::Ty;
use std::fmt::Debug; use std::fmt::Debug;
pub trait Backend { pub trait BackendTypes {
type Value: Debug + PartialEq + Copy; type Value: Debug + PartialEq + Copy;
type BasicBlock; type BasicBlock;
type Type: Debug + PartialEq + Copy; type Type: Debug + PartialEq + Copy;
type Context; type Context;
} }
pub trait Backend<'tcx>:
BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
{
}
impl<'tcx, T> Backend<'tcx> for T where
Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
{}

View file

@ -8,48 +8,23 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use super::HasCodegen;
use builder::MemFlags;
use common::*; use common::*;
use libc::c_char; use libc::c_char;
use rustc::ty::TyCtxt;
use rustc::ty::layout::{Align, Size};
use rustc::session::Session; use rustc::session::Session;
use builder::MemFlags; use rustc::ty::layout::{Align, Size};
use super::backend::Backend;
use super::type_::TypeMethods;
use super::consts::ConstMethods;
use super::intrinsic::IntrinsicDeclarationMethods;
use std::borrow::Cow; use std::borrow::Cow;
use std::ops::Range; use std::ops::Range;
use syntax::ast::AsmDialect; use syntax::ast::AsmDialect;
pub trait HasCodegen: Backend { pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen<'tcx> {
type CodegenCx: TypeMethods + ConstMethods + IntrinsicDeclarationMethods + Backend< fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
Value = Self::Value,
BasicBlock = Self::BasicBlock,
Type = Self::Type,
Context = Self::Context,
>;
}
impl<T: HasCodegen> Backend for T {
type Value = <T::CodegenCx as Backend>::Value;
type BasicBlock = <T::CodegenCx as Backend>::BasicBlock;
type Type = <T::CodegenCx as Backend>::Type;
type Context = <T::CodegenCx as Backend>::Context;
}
pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
fn new_block<'b>(
cx: &'a Self::CodegenCx,
llfn: Self::Value,
name: &'b str
) -> Self;
fn with_cx(cx: &'a Self::CodegenCx) -> Self; fn with_cx(cx: &'a Self::CodegenCx) -> Self;
fn build_sibling_block<'b>(&self, name: &'b str) -> Self; fn build_sibling_block<'b>(&self, name: &'b str) -> Self;
fn sess(&self) -> &Session; fn sess(&self) -> &Session;
fn cx(&self) -> &'a Self::CodegenCx; fn cx(&self) -> &'a Self::CodegenCx; // FIXME(eddyb) remove 'a
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>;
fn llfn(&self) -> Self::Value; fn llfn(&self) -> Self::Value;
fn llbb(&self) -> Self::BasicBlock; fn llbb(&self) -> Self::BasicBlock;
fn count_insn(&self, category: &str); fn count_insn(&self, category: &str);
@ -60,25 +35,15 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
fn ret_void(&self); fn ret_void(&self);
fn ret(&self, v: Self::Value); fn ret(&self, v: Self::Value);
fn br(&self, dest: Self::BasicBlock); fn br(&self, dest: Self::BasicBlock);
fn cond_br( fn cond_br(&self, cond: Self::Value, then_llbb: Self::BasicBlock, else_llbb: Self::BasicBlock);
&self, fn switch(&self, v: Self::Value, else_llbb: Self::BasicBlock, num_cases: usize) -> Self::Value;
cond: Self::Value,
then_llbb: Self::BasicBlock,
else_llbb: Self::BasicBlock,
);
fn switch(
&self,
v: Self::Value,
else_llbb: Self::BasicBlock,
num_cases: usize,
) -> Self::Value;
fn invoke( fn invoke(
&self, &self,
llfn: Self::Value, llfn: Self::Value,
args: &[Self::Value], args: &[Self::Value],
then: Self::BasicBlock, then: Self::BasicBlock,
catch: Self::BasicBlock, catch: Self::BasicBlock,
bundle: Option<&OperandBundleDef<Self::Value>> bundle: Option<&OperandBundleDef<Self::Value>>,
) -> Self::Value; ) -> Self::Value;
fn unreachable(&self); fn unreachable(&self);
fn add(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn add(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
@ -117,7 +82,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
ty: Self::Type, ty: Self::Type,
len: Self::Value, len: Self::Value,
name: &str, name: &str,
align: Align align: Align,
) -> Self::Value; ) -> Self::Value;
fn load(&self, ptr: Self::Value, align: Align) -> Self::Value; fn load(&self, ptr: Self::Value, align: Align) -> Self::Value;
@ -135,13 +100,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
align: Align, align: Align,
flags: MemFlags, flags: MemFlags,
) -> Self::Value; ) -> Self::Value;
fn atomic_store( fn atomic_store(&self, val: Self::Value, ptr: Self::Value, order: AtomicOrdering, size: Size);
&self,
val: Self::Value,
ptr: Self::Value,
order: AtomicOrdering,
size: Size
);
fn gep(&self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value; fn gep(&self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
fn inbounds_gep(&self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value; fn inbounds_gep(&self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
@ -174,16 +133,27 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
output: Self::Type, output: Self::Type,
volatile: bool, volatile: bool,
alignstack: bool, alignstack: bool,
dia: AsmDialect dia: AsmDialect,
) -> Option<Self::Value>; ) -> Option<Self::Value>;
fn memcpy(
fn memcpy(&self, dst: Self::Value, dst_align: Align, &self,
src: Self::Value, src_align: Align, dst: Self::Value,
size: Self::Value, flags: MemFlags); dst_align: Align,
fn memmove(&self, dst: Self::Value, dst_align: Align, src: Self::Value,
src: Self::Value, src_align: Align, src_align: Align,
size: Self::Value, flags: MemFlags); size: Self::Value,
flags: MemFlags,
);
fn memmove(
&self,
dst: Self::Value,
dst_align: Align,
src: Self::Value,
src_align: Align,
size: Self::Value,
flags: MemFlags,
);
fn memset( fn memset(
&self, &self,
ptr: Self::Value, ptr: Self::Value,
@ -196,18 +166,15 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
fn minnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn minnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
fn maxnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn maxnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
fn select( fn select(
&self, cond: Self::Value, &self,
cond: Self::Value,
then_val: Self::Value, then_val: Self::Value,
else_val: Self::Value, else_val: Self::Value,
) -> Self::Value; ) -> Self::Value;
fn va_arg(&self, list: Self::Value, ty: Self::Type) -> Self::Value; fn va_arg(&self, list: Self::Value, ty: Self::Type) -> Self::Value;
fn extract_element(&self, vec: Self::Value, idx: Self::Value) -> Self::Value; fn extract_element(&self, vec: Self::Value, idx: Self::Value) -> Self::Value;
fn insert_element( fn insert_element(&self, vec: Self::Value, elt: Self::Value, idx: Self::Value) -> Self::Value;
&self, vec: Self::Value,
elt: Self::Value,
idx: Self::Value,
) -> Self::Value;
fn shuffle_vector(&self, v1: Self::Value, v2: Self::Value, mask: Self::Value) -> Self::Value; fn shuffle_vector(&self, v1: Self::Value, v2: Self::Value, mask: Self::Value) -> Self::Value;
fn vector_splat(&self, num_elts: usize, elt: Self::Value) -> Self::Value; fn vector_splat(&self, num_elts: usize, elt: Self::Value) -> Self::Value;
fn vector_reduce_fadd_fast(&self, acc: Self::Value, src: Self::Value) -> Self::Value; fn vector_reduce_fadd_fast(&self, acc: Self::Value, src: Self::Value) -> Self::Value;
@ -224,36 +191,15 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
fn vector_reduce_min(&self, src: Self::Value, is_signed: bool) -> Self::Value; fn vector_reduce_min(&self, src: Self::Value, is_signed: bool) -> Self::Value;
fn vector_reduce_max(&self, src: Self::Value, is_signed: bool) -> Self::Value; fn vector_reduce_max(&self, src: Self::Value, is_signed: bool) -> Self::Value;
fn extract_value(&self, agg_val: Self::Value, idx: u64) -> Self::Value; fn extract_value(&self, agg_val: Self::Value, idx: u64) -> Self::Value;
fn insert_value( fn insert_value(&self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value;
&self,
agg_val: Self::Value,
elt: Self::Value,
idx: u64
) -> Self::Value;
fn landing_pad( fn landing_pad(&self, ty: Self::Type, pers_fn: Self::Value, num_clauses: usize) -> Self::Value;
&self,
ty: Self::Type,
pers_fn: Self::Value,
num_clauses: usize
) -> Self::Value;
fn add_clause(&self, landing_pad: Self::Value, clause: Self::Value); fn add_clause(&self, landing_pad: Self::Value, clause: Self::Value);
fn set_cleanup(&self, landing_pad: Self::Value); fn set_cleanup(&self, landing_pad: Self::Value);
fn resume(&self, exn: Self::Value) -> Self::Value; fn resume(&self, exn: Self::Value) -> Self::Value;
fn cleanup_pad( fn cleanup_pad(&self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Value;
&self, fn cleanup_ret(&self, cleanup: Self::Value, unwind: Option<Self::BasicBlock>) -> Self::Value;
parent: Option<Self::Value>, fn catch_pad(&self, parent: Self::Value, args: &[Self::Value]) -> Self::Value;
args: &[Self::Value]
) -> Self::Value;
fn cleanup_ret(
&self, cleanup: Self::Value,
unwind: Option<Self::BasicBlock>,
) -> Self::Value;
fn catch_pad(
&self,
parent: Self::Value,
args: &[Self::Value]
) -> Self::Value;
fn catch_ret(&self, pad: Self::Value, unwind: Self::BasicBlock) -> Self::Value; fn catch_ret(&self, pad: Self::Value, unwind: Self::BasicBlock) -> Self::Value;
fn catch_switch( fn catch_switch(
&self, &self,
@ -285,23 +231,25 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
fn add_incoming_to_phi(&self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock); fn add_incoming_to_phi(&self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock);
fn set_invariant_load(&self, load: Self::Value); fn set_invariant_load(&self, load: Self::Value);
fn check_store( fn check_store(&self, val: Self::Value, ptr: Self::Value) -> Self::Value;
&self,
val: Self::Value,
ptr: Self::Value
) -> Self::Value;
fn check_call<'b>( fn check_call<'b>(
&self, &self,
typ: &str, typ: &str,
llfn: Self::Value, llfn: Self::Value,
args: &'b [Self::Value] args: &'b [Self::Value],
) -> Cow<'b, [Self::Value]> where [Self::Value]: ToOwned; ) -> Cow<'b, [Self::Value]>
where
[Self::Value]: ToOwned;
fn lifetime_start(&self, ptr: Self::Value, size: Size); fn lifetime_start(&self, ptr: Self::Value, size: Size);
fn lifetime_end(&self, ptr: Self::Value, size: Size); fn lifetime_end(&self, ptr: Self::Value, size: Size);
fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: Self::Value, size: Size); fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: Self::Value, size: Size);
fn call(&self, llfn: Self::Value, args: &[Self::Value], fn call(
bundle: Option<&OperandBundleDef<Self::Value>>) -> Self::Value; &self,
llfn: Self::Value,
args: &[Self::Value],
bundle: Option<&OperandBundleDef<Self::Value>>,
) -> Self::Value;
fn zext(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn zext(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
} }

View file

@ -11,7 +11,7 @@
use super::Backend; use super::Backend;
use syntax::symbol::LocalInternedString; use syntax::symbol::LocalInternedString;
pub trait ConstMethods: Backend { pub trait ConstMethods<'tcx>: Backend<'tcx> {
// Constant constructors // Constant constructors
fn const_null(&self, t: Self::Type) -> Self::Value; fn const_null(&self, t: Self::Type) -> Self::Value;
fn const_undef(&self, t: Self::Type) -> Self::Value; fn const_undef(&self, t: Self::Type) -> Self::Value;
@ -24,22 +24,10 @@ pub trait ConstMethods: Backend {
fn const_u64(&self, i: u64) -> Self::Value; fn const_u64(&self, i: u64) -> Self::Value;
fn const_usize(&self, i: u64) -> Self::Value; fn const_usize(&self, i: u64) -> Self::Value;
fn const_u8(&self, i: u8) -> Self::Value; fn const_u8(&self, i: u8) -> Self::Value;
fn const_cstr( fn const_cstr(&self, s: LocalInternedString, null_terminated: bool) -> Self::Value;
&self,
s: LocalInternedString,
null_terminated: bool,
) -> Self::Value;
fn const_str_slice(&self, s: LocalInternedString) -> Self::Value; fn const_str_slice(&self, s: LocalInternedString) -> Self::Value;
fn const_fat_ptr( fn const_fat_ptr(&self, ptr: Self::Value, meta: Self::Value) -> Self::Value;
&self, fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
ptr: Self::Value,
meta: Self::Value
) -> Self::Value;
fn const_struct(
&self,
elts: &[Self::Value],
packed: bool
) -> Self::Value;
fn const_array(&self, ty: Self::Type, elts: &[Self::Value]) -> Self::Value; fn const_array(&self, ty: Self::Type, elts: &[Self::Value]) -> Self::Value;
fn const_vector(&self, elts: &[Self::Value]) -> Self::Value; fn const_vector(&self, elts: &[Self::Value]) -> Self::Value;
fn const_bytes(&self, bytes: &[u8]) -> Self::Value; fn const_bytes(&self, bytes: &[u8]) -> Self::Value;

View file

@ -0,0 +1,16 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use super::backend::Backend;
use rustc::ty::Ty;
pub trait DebugInfoMethods<'tcx>: Backend<'tcx> {
fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value);
}

View file

@ -9,13 +9,13 @@
// except according to those terms. // except according to those terms.
use super::backend::Backend; use super::backend::Backend;
use super::builder::HasCodegen; use super::builder::BuilderMethods;
use abi::FnType;
use mir::operand::OperandRef; use mir::operand::OperandRef;
use rustc::ty::Ty; use rustc::ty::Ty;
use abi::FnType;
use syntax_pos::Span; use syntax_pos::Span;
pub trait IntrinsicCallMethods<'a, 'tcx: 'a>: HasCodegen { pub trait IntrinsicCallMethods<'a, 'tcx: 'a>: BuilderMethods<'a, 'tcx> {
fn codegen_intrinsic_call( fn codegen_intrinsic_call(
&self, &self,
callee_ty: Ty<'tcx>, callee_ty: Ty<'tcx>,
@ -26,10 +26,7 @@ pub trait IntrinsicCallMethods<'a, 'tcx: 'a>: HasCodegen {
); );
} }
pub trait IntrinsicDeclarationMethods: Backend { pub trait IntrinsicDeclarationMethods<'tcx>: Backend<'tcx> {
fn get_intrinsic(&self, key: &str) -> Self::Value; fn get_intrinsic(&self, key: &str) -> Self::Value;
fn declare_intrinsic( fn declare_intrinsic(&self, key: &str) -> Option<Self::Value>;
&self,
key: &str
) -> Option<Self::Value>;
} }

View file

@ -0,0 +1,21 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use super::backend::Backend;
use rustc::ty::{self, Instance, Ty};
use rustc::util::nodemap::FxHashMap;
use std::cell::RefCell;
pub trait MiscMethods<'tcx>: Backend<'tcx> {
fn vtables(
&self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>), Self::Value>>;
fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value;
}

View file

@ -8,16 +8,49 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
mod builder;
mod backend; mod backend;
mod builder;
mod consts; mod consts;
mod type_; mod debuginfo;
mod intrinsic; mod intrinsic;
mod misc;
mod statics; mod statics;
mod type_;
pub use self::builder::{BuilderMethods, HasCodegen}; pub use self::backend::{Backend, BackendTypes};
pub use self::backend::Backend; pub use self::builder::BuilderMethods;
pub use self::consts::ConstMethods; pub use self::consts::ConstMethods;
pub use self::type_::{TypeMethods, BaseTypeMethods, DerivedTypeMethods}; pub use self::debuginfo::DebugInfoMethods;
pub use self::intrinsic::{IntrinsicCallMethods, IntrinsicDeclarationMethods}; pub use self::intrinsic::{IntrinsicCallMethods, IntrinsicDeclarationMethods};
pub use self::misc::MiscMethods;
pub use self::statics::StaticMethods; pub use self::statics::StaticMethods;
pub use self::type_::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMethods};
pub trait CodegenMethods<'tcx>:
Backend<'tcx>
+ TypeMethods<'tcx>
+ MiscMethods<'tcx>
+ ConstMethods<'tcx>
+ StaticMethods<'tcx>
+ DebugInfoMethods<'tcx>
{
}
impl<'tcx, T> CodegenMethods<'tcx> for T where
Self: Backend<'tcx>
+ TypeMethods<'tcx>
+ MiscMethods<'tcx>
+ ConstMethods<'tcx>
+ StaticMethods<'tcx>
+ DebugInfoMethods<'tcx>
{}
pub trait HasCodegen<'tcx>: Backend<'tcx> {
type CodegenCx: CodegenMethods<'tcx>
+ BackendTypes<
Value = Self::Value,
BasicBlock = Self::BasicBlock,
Type = Self::Type,
Context = Self::Context,
>;
}

View file

@ -8,29 +8,15 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use rustc::ty::layout::Align;
use rustc::hir::def_id::DefId;
use super::backend::Backend; use super::backend::Backend;
use rustc::hir::def_id::DefId;
use rustc::ty::layout::Align;
pub trait StaticMethods<'tcx>: Backend { pub trait StaticMethods<'tcx>: Backend<'tcx> {
fn static_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; fn static_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
fn static_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; fn static_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
fn static_addr_of_mut( fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
&self, fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
cv: Self::Value,
align: Align,
kind: Option<&str>,
) -> Self::Value;
fn static_addr_of(
&self,
cv: Self::Value,
align: Align,
kind: Option<&str>,
) -> Self::Value;
fn get_static(&self, def_id: DefId) -> Self::Value; fn get_static(&self, def_id: DefId) -> Self::Value;
fn codegen_static( fn codegen_static(&self, def_id: DefId, is_mutable: bool);
&self,
def_id: DefId,
is_mutable: bool,
);
} }

View file

@ -10,10 +10,14 @@
use super::backend::Backend; use super::backend::Backend;
use common::TypeKind; use common::TypeKind;
use syntax::ast; use rustc::ty::layout::TyLayout;
use rustc::ty::layout::{self, Align, Size}; use rustc::ty::layout::{self, Align, Size};
use rustc::ty::Ty;
use rustc::util::nodemap::FxHashMap;
use std::cell::RefCell;
use syntax::ast;
pub trait BaseTypeMethods: Backend { pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn type_void(&self) -> Self::Type; fn type_void(&self) -> Self::Type;
fn type_metadata(&self) -> Self::Type; fn type_metadata(&self) -> Self::Type;
fn type_i1(&self) -> Self::Type; fn type_i1(&self) -> Self::Type;
@ -43,32 +47,31 @@ pub trait BaseTypeMethods: Backend {
fn int_width(&self, ty: Self::Type) -> u64; fn int_width(&self, ty: Self::Type) -> u64;
fn val_ty(&self, v: Self::Value) -> Self::Type; fn val_ty(&self, v: Self::Value) -> Self::Type;
fn scalar_lltypes(&self) -> &RefCell<FxHashMap<Ty<'tcx>, Self::Type>>;
} }
pub trait DerivedTypeMethods: Backend { pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> {
fn type_bool(&self) -> Self::Type; fn type_bool(&self) -> Self::Type;
fn type_i8p(&self) -> Self::Type; fn type_i8p(&self) -> Self::Type;
fn type_isize(&self) -> Self::Type; fn type_isize(&self) -> Self::Type;
fn type_int(&self) -> Self::Type; fn type_int(&self) -> Self::Type;
fn type_int_from_ty( fn type_int_from_ty(&self, t: ast::IntTy) -> Self::Type;
&self, fn type_uint_from_ty(&self, t: ast::UintTy) -> Self::Type;
t: ast::IntTy fn type_float_from_ty(&self, t: ast::FloatTy) -> Self::Type;
) -> Self::Type;
fn type_uint_from_ty(
&self,
t: ast::UintTy
) -> Self::Type;
fn type_float_from_ty(
&self,
t: ast::FloatTy
) -> Self::Type;
fn type_from_integer(&self, i: layout::Integer) -> Self::Type; fn type_from_integer(&self, i: layout::Integer) -> Self::Type;
fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type; fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
fn type_padding_filler( fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;
&self,
size: Size,
align: Align
) -> Self::Type;
} }
pub trait TypeMethods: BaseTypeMethods + DerivedTypeMethods {} pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
fn backend_type(&self, ty: TyLayout<'tcx>) -> Self::Type;
}
pub trait TypeMethods<'tcx>:
BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
{
}
impl<T> TypeMethods<'tcx> for T where
Self: BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
{}

View file

@ -25,7 +25,7 @@ use glue;
use type_::Type; use type_::Type;
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::layout::LayoutOf; use rustc::ty::layout::{LayoutOf, HasTyCtxt};
use rustc::hir; use rustc::hir;
use syntax::ast; use syntax::ast;
use syntax::symbol::Symbol; use syntax::symbol::Symbol;

View file

@ -10,16 +10,14 @@
use abi::{FnType, FnTypeExt}; use abi::{FnType, FnTypeExt};
use callee; use callee;
use context::CodegenCx;
use builder::Builder; use builder::Builder;
use monomorphize; use monomorphize;
use value::Value; use value::Value;
use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods, StaticMethods}; use interfaces::*;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::layout::HasDataLayout; use rustc::ty::layout::HasTyCtxt;
use debuginfo;
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct VirtualIndex(u64); pub struct VirtualIndex(u64);
@ -82,17 +80,17 @@ impl<'a, 'tcx> VirtualIndex {
/// The `trait_ref` encodes the erased self type. Hence if we are /// The `trait_ref` encodes the erased self type. Hence if we are
/// making an object `Foo<Trait>` from a value of type `Foo<T>`, then /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
/// `trait_ref` would map `T:Trait`. /// `trait_ref` would map `T:Trait`.
pub fn get_vtable( pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &CodegenCx<'ll, 'tcx>, cx: &Cx,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_ref: ty::PolyExistentialTraitRef<'tcx>, trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> &'ll Value { ) -> Cx::Value {
let tcx = cx.tcx; let tcx = cx.tcx();
debug!("get_vtable(ty={:?}, trait_ref={:?})", ty, trait_ref); debug!("get_vtable(ty={:?}, trait_ref={:?})", ty, trait_ref);
// Check the cache. // Check the cache.
if let Some(&val) = cx.vtables.borrow().get(&(ty, trait_ref)) { if let Some(&val) = cx.vtables().borrow().get(&(ty, trait_ref)) {
return val; return val;
} }
@ -106,13 +104,13 @@ pub fn get_vtable(
}) })
}); });
let (size, align) = cx.size_and_align_of(ty); let (size, align) = cx.layout_of(ty).size_and_align();
// ///////////////////////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////////////////////
// If you touch this code, be sure to also make the corresponding changes to // If you touch this code, be sure to also make the corresponding changes to
// `get_vtable` in rust_mir/interpret/traits.rs // `get_vtable` in rust_mir/interpret/traits.rs
// ///////////////////////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////////////////////
let components: Vec<_> = [ let components: Vec<_> = [
callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)), cx.get_fn(monomorphize::resolve_drop_in_place(cx.tcx(), ty)),
cx.const_usize(size.bytes()), cx.const_usize(size.bytes()),
cx.const_usize(align.abi()) cx.const_usize(align.abi())
].iter().cloned().chain(methods).collect(); ].iter().cloned().chain(methods).collect();
@ -121,8 +119,8 @@ pub fn get_vtable(
let align = cx.data_layout().pointer_align; let align = cx.data_layout().pointer_align;
let vtable = cx.static_addr_of(vtable_const, align, Some("vtable")); let vtable = cx.static_addr_of(vtable_const, align, Some("vtable"));
debuginfo::create_vtable_metadata(cx, ty, vtable); cx.create_vtable_metadata(ty, vtable);
cx.vtables.borrow_mut().insert((ty, trait_ref), vtable); cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
vtable vtable
} }

View file

@ -11,7 +11,7 @@
use llvm::{self, BasicBlock}; use llvm::{self, BasicBlock};
use rustc::middle::lang_items; use rustc::middle::lang_items;
use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::{self, LayoutOf}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
use rustc::mir; use rustc::mir;
use rustc::mir::interpret::EvalErrorKind; use rustc::mir::interpret::EvalErrorKind;
use abi::{Abi, ArgType, ArgTypeExt, FnType, FnTypeExt, LlvmType, PassMode}; use abi::{Abi, ArgType, ArgTypeExt, FnType, FnTypeExt, LlvmType, PassMode};
@ -57,7 +57,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
debug!("codegen_terminator: {:?}", terminator); debug!("codegen_terminator: {:?}", terminator);
// Create the cleanup bundle, if needed. // Create the cleanup bundle, if needed.
let tcx = bx.tcx(); let tcx = self.cx.tcx;
let span = terminator.source_info.span; let span = terminator.source_info.span;
let funclet_bb = self.cleanup_kinds[bb].funclet_bb(bb); let funclet_bb = self.cleanup_kinds[bb].funclet_bb(bb);
let funclet = funclet_bb.and_then(|funclet_bb| self.funclets[funclet_bb].as_ref()); let funclet = funclet_bb.and_then(|funclet_bb| self.funclets[funclet_bb].as_ref());

View file

@ -16,7 +16,7 @@ use rustc::mir;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use rustc::mir::interpret::{GlobalId, Pointer, Scalar, Allocation, ConstValue, AllocType}; use rustc::mir::interpret::{GlobalId, Pointer, Scalar, Allocation, ConstValue, AllocType};
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size}; use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size, HasTyCtxt};
use builder::Builder; use builder::Builder;
use common::{CodegenCx}; use common::{CodegenCx};
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;

View file

@ -13,7 +13,7 @@ use llvm::{self, BasicBlock};
use llvm::debuginfo::DIScope; use llvm::debuginfo::DIScope;
use llvm_util; use llvm_util;
use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
use rustc::ty::layout::{LayoutOf, TyLayout}; use rustc::ty::layout::{LayoutOf, TyLayout, HasTyCtxt};
use rustc::mir::{self, Mir}; use rustc::mir::{self, Mir};
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::session::config::DebugInfo; use rustc::session::config::DebugInfo;

View file

@ -10,7 +10,7 @@
use llvm::{self, LLVMConstInBoundsGEP}; use llvm::{self, LLVMConstInBoundsGEP};
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size, VariantIdx}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size, VariantIdx, HasTyCtxt};
use rustc::mir; use rustc::mir;
use rustc::mir::tcx::PlaceTy; use rustc::mir::tcx::PlaceTy;
use base; use base;

View file

@ -10,7 +10,7 @@
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::cast::{CastTy, IntTy}; use rustc::ty::cast::{CastTy, IntTy};
use rustc::ty::layout::{self, LayoutOf}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
use rustc::mir; use rustc::mir;
use rustc::middle::lang_items::ExchangeMallocFnLangItem; use rustc::middle::lang_items::ExchangeMallocFnLangItem;
use rustc_apfloat::{ieee, Float, Status, Round}; use rustc_apfloat::{ieee, Float, Status, Round};
@ -488,7 +488,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => { mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
assert!(bx.cx().type_is_sized(ty)); assert!(bx.cx().type_is_sized(ty));
let val = bx.cx().const_usize(bx.cx().size_of(ty).bytes()); let val = bx.cx().const_usize(bx.cx().size_of(ty).bytes());
let tcx = bx.tcx(); let tcx = self.cx.tcx;
(bx, OperandRef { (bx, OperandRef {
val: OperandValue::Immediate(val), val: OperandValue::Immediate(val),
layout: self.cx.layout_of(tcx.types.usize), layout: self.cx.layout_of(tcx.types.usize),

View file

@ -15,16 +15,21 @@ pub use llvm::Type;
use llvm; use llvm;
use llvm::{Bool, False, True}; use llvm::{Bool, False, True};
use context::CodegenCx; use context::CodegenCx;
use interfaces::{BaseTypeMethods, DerivedTypeMethods, TypeMethods}; use interfaces::*;
use value::Value; use value::Value;
use syntax::ast; use syntax::ast;
use rustc::ty::layout::{self, Align, Size}; use rustc::ty::layout::{self, Align, Size};
use rustc::util::nodemap::FxHashMap;
use rustc::ty::Ty;
use rustc::ty::layout::TyLayout;
use rustc_data_structures::small_c_str::SmallCStr; use rustc_data_structures::small_c_str::SmallCStr;
use common::{self, TypeKind}; use common::{self, TypeKind};
use type_of::LayoutLlvmExt;
use std::fmt; use std::fmt;
use std::cell::RefCell;
use libc::c_uint; use libc::c_uint;
@ -42,7 +47,7 @@ impl fmt::Debug for Type {
} }
} }
impl BaseTypeMethods for CodegenCx<'ll, 'tcx> { impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn type_void(&self) -> &'ll Type { fn type_void(&self) -> &'ll Type {
unsafe { unsafe {
llvm::LLVMVoidTypeInContext(self.llcx) llvm::LLVMVoidTypeInContext(self.llcx)
@ -234,6 +239,10 @@ impl BaseTypeMethods for CodegenCx<'ll, 'tcx> {
fn val_ty(&self, v: &'ll Value) -> &'ll Type { fn val_ty(&self, v: &'ll Value) -> &'ll Type {
common::val_ty(v) common::val_ty(v)
} }
fn scalar_lltypes(&self) -> &RefCell<FxHashMap<Ty<'tcx>, Self::Type>> {
&self.scalar_lltypes
}
} }
impl Type { impl Type {
@ -264,7 +273,7 @@ impl Type {
} }
} }
impl DerivedTypeMethods for CodegenCx<'ll, 'tcx> { impl DerivedTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn type_bool(&self) -> &'ll Type { fn type_bool(&self) -> &'ll Type {
self.type_i8() self.type_i8()
} }
@ -358,4 +367,8 @@ impl DerivedTypeMethods for CodegenCx<'ll, 'tcx> {
} }
} }
impl TypeMethods for CodegenCx<'ll, 'tcx> {} impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn backend_type(&self, ty: TyLayout<'tcx>) -> &'ll Type {
ty.llvm_type(&self)
}
}