提交 034f6975 编写于 作者: D Denis Merigoux 提交者: Eduard-Mihai Burtescu

Generalized base::unsized_info

上级 484e07c2
......@@ -55,7 +55,6 @@
use callee;
use rustc_mir::monomorphize::item::DefPathBasedNames;
use common::{self, IntPredicate, RealPredicate, TypeKind};
use consts;
use context::CodegenCx;
use debuginfo;
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
/// in an upcast, where the new vtable for an object will be derived
/// from the old one.
pub fn unsized_info(
cx: &CodegenCx<'ll, 'tcx>,
pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &Cx,
source: Ty<'tcx>,
target: Ty<'tcx>,
old_info: Option<&'ll Value>,
) -> &'ll Value {
let (source, target) = cx.tcx.struct_lockstep_tails(source, target);
old_info: Option<Cx::Value>,
) -> Cx::Value {
let (source, target) = cx.tcx().struct_lockstep_tails(source, target);
match (&source.sty, &target.sty) {
(&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(..)) => {
// 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")
}
(_, &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);
consts::ptrcast(meth::get_vtable(cx, source, data.principal()),
vtable_ptr.llvm_type(cx))
cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()),
cx.backend_type(vtable_ptr))
}
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}",
source,
......
......@@ -15,8 +15,8 @@
use type_::Type;
use value::Value;
use libc::{c_uint, c_char};
use rustc::ty::TyCtxt;
use rustc::ty::layout::{Align, Size};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::{Align, Size, TyLayout};
use rustc::session::{config, Session};
use rustc_data_structures::small_c_str::SmallCStr;
use interfaces::*;
......@@ -56,7 +56,36 @@ pub struct MemFlags: u8 {
}
}
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>;
}
......@@ -98,10 +127,6 @@ fn sess(&self) -> &Session {
self.cx.sess()
}
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.cx.tcx
}
fn llfn(&self) -> &'ll Value {
unsafe {
llvm::LLVMGetBasicBlockParent(self.llbb())
......
......@@ -22,7 +22,7 @@
use monomorphize::Instance;
use type_of::LayoutLlvmExt;
use value::Value;
use interfaces::BaseTypeMethods;
use interfaces::*;
use rustc::hir::def_id::DefId;
use rustc::ty::{self, TypeFoldable};
......@@ -206,15 +206,16 @@ pub fn get_fn(
llfn
}
pub fn resolve_and_get_fn(
cx: &CodegenCx<'ll, 'tcx>,
pub fn resolve_and_get_fn<'tcx,
Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
>(
cx: &Cx,
def_id: DefId,
substs: &'tcx Substs<'tcx>,
) -> &'ll Value {
get_fn(
cx,
) -> Cx::Value {
cx.get_fn(
ty::Instance::resolve(
cx.tcx,
cx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
substs
......@@ -222,15 +223,16 @@ pub fn resolve_and_get_fn(
)
}
pub fn resolve_and_get_fn_for_vtable(
cx: &CodegenCx<'ll, 'tcx>,
pub fn resolve_and_get_fn_for_vtable<'tcx,
Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
>(
cx: &Cx,
def_id: DefId,
substs: &'tcx Substs<'tcx>,
) -> &'ll Value {
get_fn(
cx,
) -> Cx::Value {
cx.get_fn(
ty::Instance::resolve_for_vtable(
cx.tcx,
cx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
substs
......
......@@ -23,12 +23,11 @@
use type_::Type;
use type_of::LayoutLlvmExt;
use value::Value;
use interfaces::{Backend, ConstMethods, BaseTypeMethods};
use interfaces::{BackendTypes, BuilderMethods, ConstMethods, BaseTypeMethods};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::{HasDataLayout, LayoutOf};
use rustc::hir;
use interfaces::BuilderMethods;
use libc::{c_uint, c_char};
......@@ -213,15 +212,14 @@ pub fn bundle(&self) -> &OperandBundleDef<'ll, &'ll Value> {
}
}
impl Backend for CodegenCx<'ll, 'tcx> {
impl BackendTypes for CodegenCx<'ll, 'tcx> {
type Value = &'ll Value;
type BasicBlock = &'ll BasicBlock;
type Type = &'ll Type;
type Context = &'ll llvm::Context;
}
impl<'ll, 'tcx: 'll> ConstMethods for CodegenCx<'ll, 'tcx> {
impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// LLVM constant constructors.
fn const_null(&self, t: &'ll Type) -> &'ll Value {
unsafe {
......@@ -319,7 +317,7 @@ fn const_cstr(
fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
let len = s.len();
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))
}
......
......@@ -201,7 +201,7 @@ fn get_static(&self, def_id: DefId) -> &'ll Value {
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) {
Node::Item(&hir::Item {
ref attrs, span, node: hir::ItemKind::Static(..), ..
......@@ -329,7 +329,7 @@ fn codegen_static(
let instance = Instance::mono(self.tcx, def_id);
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 {
g
} else {
......
......@@ -23,7 +23,7 @@
use monomorphize::partitioning::CodegenUnit;
use type_::Type;
use type_of::PointeeInfo;
use interfaces::{BaseTypeMethods, DerivedTypeMethods, IntrinsicDeclarationMethods};
use interfaces::*;
use rustc_data_structures::base_n;
use rustc_data_structures::small_c_str::SmallCStr;
......@@ -322,7 +322,18 @@ pub fn sess<'a>(&'a self) -> &'a Session {
}
}
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 {
if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
return v;
......
......@@ -17,6 +17,7 @@
use super::namespace::mangled_name_of_instance;
use super::type_names::compute_debuginfo_type_name;
use super::{CrateDebugContext};
use interfaces::*;
use abi;
use interfaces::ConstMethods;
use value::Value;
......@@ -1983,58 +1984,60 @@ pub fn extend_scope_to_file(
}
}
/// 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(
cx: &CodegenCx<'ll, 'tcx>,
ty: ty::Ty<'tcx>,
vtable: &'ll Value,
) {
if cx.dbg_cx.is_none() {
return;
}
let type_metadata = type_metadata(cx, ty, syntax_pos::DUMMY_SP);
unsafe {
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
// later on in llvm/lib/IR/Value.cpp.
let empty_array = create_DIArray(DIB(cx), &[]);
let name = const_cstr!("vtable");
impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
/// Creates debug information for the given vtable, which is for the
/// given type.
///
/// Adds the created metadata nodes directly to the crate's IR.
fn create_vtable_metadata(
&self,
ty: ty::Ty<'tcx>,
vtable: &'ll Value,
) {
if self.dbg_cx.is_none() {
return;
}
// Create a new one each time. We don't want metadata caching
// here, because each vtable will refer to a unique containing
// type.
let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
DIB(cx),
NO_SCOPE_METADATA,
name.as_ptr(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
Size::ZERO.bits(),
cx.tcx.data_layout.pointer_align.abi_bits() as u32,
DIFlags::FlagArtificial,
None,
empty_array,
0,
Some(type_metadata),
name.as_ptr()
);
let type_metadata = type_metadata(&self, ty, syntax_pos::DUMMY_SP);
llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
NO_SCOPE_METADATA,
name.as_ptr(),
ptr::null(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
vtable_type,
true,
vtable,
None,
0);
unsafe {
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
// later on in llvm/lib/IR/Value.cpp.
let empty_array = create_DIArray(DIB(&self), &[]);
let name = const_cstr!("vtable");
// Create a new one each time. We don't want metadata caching
// here, because each vtable will refer to a unique containing
// type.
let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
DIB(&self),
NO_SCOPE_METADATA,
name.as_ptr(),
unknown_file_metadata(&self),
UNKNOWN_LINE_NUMBER,
Size::ZERO.bits(),
self.tcx.data_layout.pointer_align.abi_bits() as u32,
DIFlags::FlagArtificial,
None,
empty_array,
0,
Some(type_metadata),
name.as_ptr()
);
llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(&self),
NO_SCOPE_METADATA,
name.as_ptr(),
ptr::null(),
unknown_file_metadata(&self),
UNKNOWN_LINE_NUMBER,
vtable_type,
true,
vtable,
None,
0);
}
}
}
......@@ -58,7 +58,6 @@
pub use self::create_scope_map::{create_mir_scopes, MirDebugScope};
pub use self::source_loc::start_emitting_source_locations;
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::source_loc::set_source_location;
......
......@@ -17,7 +17,7 @@
use builder::Builder;
use common::*;
use meth;
use rustc::ty::layout::LayoutOf;
use rustc::ty::layout::{LayoutOf, HasTyCtxt};
use rustc::ty::{self, Ty};
use value::Value;
use interfaces::{BuilderMethods, ConstMethods};
......
......@@ -8,11 +8,22 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout};
use rustc::ty::Ty;
use std::fmt::Debug;
pub trait Backend {
pub trait BackendTypes {
type Value: Debug + PartialEq + Copy;
type BasicBlock;
type Type: Debug + PartialEq + Copy;
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>>
{}
......@@ -8,48 +8,23 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use super::HasCodegen;
use builder::MemFlags;
use common::*;
use libc::c_char;
use rustc::ty::TyCtxt;
use rustc::ty::layout::{Align, Size};
use rustc::session::Session;
use builder::MemFlags;
use super::backend::Backend;
use super::type_::TypeMethods;
use super::consts::ConstMethods;
use super::intrinsic::IntrinsicDeclarationMethods;
use rustc::ty::layout::{Align, Size};
use std::borrow::Cow;
use std::ops::Range;
use syntax::ast::AsmDialect;
pub trait HasCodegen: Backend {
type CodegenCx: TypeMethods + ConstMethods + IntrinsicDeclarationMethods + Backend<
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;
pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen<'tcx> {
fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
fn with_cx(cx: &'a Self::CodegenCx) -> Self;
fn build_sibling_block<'b>(&self, name: &'b str) -> Self;
fn sess(&self) -> &Session;
fn cx(&self) -> &'a Self::CodegenCx;
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>;
fn cx(&self) -> &'a Self::CodegenCx; // FIXME(eddyb) remove 'a
fn llfn(&self) -> Self::Value;
fn llbb(&self) -> Self::BasicBlock;
fn count_insn(&self, category: &str);
......@@ -60,25 +35,15 @@ fn new_block<'b>(
fn ret_void(&self);
fn ret(&self, v: Self::Value);
fn br(&self, dest: Self::BasicBlock);
fn cond_br(
&self,
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 cond_br(&self, 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(
&self,
llfn: Self::Value,
args: &[Self::Value],
then: Self::BasicBlock,
catch: Self::BasicBlock,
bundle: Option<&OperandBundleDef<Self::Value>>
bundle: Option<&OperandBundleDef<Self::Value>>,
) -> Self::Value;
fn unreachable(&self);
fn add(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
......@@ -117,7 +82,7 @@ fn array_alloca(
ty: Self::Type,
len: Self::Value,
name: &str,
align: Align
align: Align,
) -> Self::Value;
fn load(&self, ptr: Self::Value, align: Align) -> Self::Value;
......@@ -135,13 +100,7 @@ fn store_with_flags(
align: Align,
flags: MemFlags,
) -> Self::Value;
fn atomic_store(
&self,
val: Self::Value,
ptr: Self::Value,
order: AtomicOrdering,
size: Size
);
fn atomic_store(&self, val: Self::Value, ptr: Self::Value, order: AtomicOrdering, size: Size);
fn 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 @@ fn inline_asm_call(
output: Self::Type,
volatile: bool,
alignstack: bool,
dia: AsmDialect
dia: AsmDialect,
) -> Option<Self::Value>;
fn memcpy(&self, dst: Self::Value, dst_align: Align,
src: Self::Value, src_align: Align,
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 memcpy(
&self,
dst: Self::Value,
dst_align: Align,
src: Self::Value,
src_align: Align,
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(
&self,
ptr: Self::Value,
......@@ -196,18 +166,15 @@ fn memset(
fn minnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
fn maxnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
fn select(
&self, cond: Self::Value,
&self,
cond: Self::Value,
then_val: Self::Value,
else_val: Self::Value,
) -> 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 insert_element(
&self, vec: Self::Value,
elt: Self::Value,
idx: Self::Value,
) -> Self::Value;
fn insert_element(&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 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;
......@@ -224,36 +191,15 @@ fn insert_element(
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 extract_value(&self, agg_val: Self::Value, idx: u64) -> Self::Value;
fn insert_value(
&self,
agg_val: Self::Value,
elt: Self::Value,
idx: u64
) -> Self::Value;
fn insert_value(&self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value;
fn landing_pad(
&self,
ty: Self::Type,
pers_fn: Self::Value,
num_clauses: usize
) -> Self::Value;
fn landing_pad(&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 set_cleanup(&self, landing_pad: Self::Value);
fn resume(&self, exn: Self::Value) -> Self::Value;
fn cleanup_pad(
&self,
parent: Option<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 cleanup_pad(&self, parent: Option<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_switch(
&self,
......@@ -285,23 +231,25 @@ fn atomic_rmw(
fn add_incoming_to_phi(&self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock);
fn set_invariant_load(&self, load: Self::Value);
fn check_store(
&self,
val: Self::Value,
ptr: Self::Value
) -> Self::Value;
fn check_store(&self, val: Self::Value, ptr: Self::Value) -> Self::Value;
fn check_call<'b>(
&self,
typ: &str,
llfn: Self::Value,
args: &'b [Self::Value]
) -> Cow<'b, [Self::Value]> where [Self::Value]: ToOwned;
args: &'b [Self::Value],
) -> Cow<'b, [Self::Value]>
where
[Self::Value]: ToOwned;
fn lifetime_start(&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(&self, llfn: Self::Value, args: &[Self::Value],
bundle: Option<&OperandBundleDef<Self::Value>>) -> Self::Value;
fn call(
&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;
}
......@@ -11,7 +11,7 @@
use super::Backend;
use syntax::symbol::LocalInternedString;
pub trait ConstMethods: Backend {
pub trait ConstMethods<'tcx>: Backend<'tcx> {
// Constant constructors
fn const_null(&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_usize(&self, i: u64) -> Self::Value;
fn const_u8(&self, i: u8) -> Self::Value;
fn const_cstr(
&self,
s: LocalInternedString,
null_terminated: bool,
) -> Self::Value;
fn const_cstr(&self, s: LocalInternedString, null_terminated: bool) -> Self::Value;
fn const_str_slice(&self, s: LocalInternedString) -> Self::Value;
fn const_fat_ptr(
&self,
ptr: Self::Value,
meta: Self::Value
) -> Self::Value;
fn const_struct(
&self,
elts: &[Self::Value],
packed: bool
) -> Self::Value;
fn const_fat_ptr(&self, 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_vector(&self, elts: &[Self::Value]) -> Self::Value;
fn const_bytes(&self, bytes: &[u8]) -> Self::Value;
......
// 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);
}
......@@ -9,13 +9,13 @@
// except according to those terms.
use super::backend::Backend;
use super::builder::HasCodegen;
use super::builder::BuilderMethods;
use abi::FnType;
use mir::operand::OperandRef;
use rustc::ty::Ty;
use abi::FnType;
use syntax_pos::Span;
pub trait IntrinsicCallMethods<'a, 'tcx: 'a>: HasCodegen {
pub trait IntrinsicCallMethods<'a, 'tcx: 'a>: BuilderMethods<'a, 'tcx> {
fn codegen_intrinsic_call(
&self,
callee_ty: Ty<'tcx>,
......@@ -26,10 +26,7 @@ fn codegen_intrinsic_call(
);
}
pub trait IntrinsicDeclarationMethods: Backend {
pub trait IntrinsicDeclarationMethods<'tcx>: Backend<'tcx> {
fn get_intrinsic(&self, key: &str) -> Self::Value;
fn declare_intrinsic(
&self,
key: &str
) -> Option<Self::Value>;
fn declare_intrinsic(&self, key: &str) -> Option<Self::Value>;
}
// 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;
}
......@@ -8,16 +8,49 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod builder;
mod backend;
mod builder;
mod consts;
mod type_;
mod debuginfo;
mod intrinsic;
mod misc;
mod statics;
mod type_;
pub use self::builder::{BuilderMethods, HasCodegen};
pub use self::backend::Backend;
pub use self::backend::{Backend, BackendTypes};
pub use self::builder::BuilderMethods;
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::misc::MiscMethods;
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,
>;
}
......@@ -8,29 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::ty::layout::Align;
use rustc::hir::def_id::DefId;
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_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
fn static_addr_of_mut(
&self,
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 static_addr_of_mut(&self, 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 codegen_static(
&self,
def_id: DefId,
is_mutable: bool,
);
fn codegen_static(&self, def_id: DefId, is_mutable: bool);
}
......@@ -10,10 +10,14 @@
use super::backend::Backend;
use common::TypeKind;
use syntax::ast;
use rustc::ty::layout::TyLayout;
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_metadata(&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 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_i8p(&self) -> Self::Type;
fn type_isize(&self) -> Self::Type;
fn type_int(&self) -> Self::Type;
fn type_int_from_ty(
&self,
t: ast::IntTy
) -> 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_int_from_ty(&self, t: ast::IntTy) -> 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_pointee_for_abi_align(&self, align: Align) -> Self::Type;
fn type_padding_filler(
&self,
size: Size,
align: Align
) -> Self::Type;
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;
}
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>
{
}
pub trait TypeMethods: BaseTypeMethods + DerivedTypeMethods {}
impl<T> TypeMethods<'tcx> for T where
Self: BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
{}
......@@ -25,7 +25,7 @@
use type_::Type;
use type_of::LayoutLlvmExt;
use rustc::ty::{self, Ty};
use rustc::ty::layout::LayoutOf;
use rustc::ty::layout::{LayoutOf, HasTyCtxt};
use rustc::hir;
use syntax::ast;
use syntax::symbol::Symbol;
......
......@@ -10,16 +10,14 @@
use abi::{FnType, FnTypeExt};
use callee;
use context::CodegenCx;
use builder::Builder;
use monomorphize;
use value::Value;
use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods, StaticMethods};
use interfaces::*;
use rustc::ty::{self, Ty};
use rustc::ty::layout::HasDataLayout;
use debuginfo;
use rustc::ty::layout::HasTyCtxt;
#[derive(Copy, Clone, Debug)]
pub struct VirtualIndex(u64);
......@@ -82,17 +80,17 @@ pub fn get_usize(
/// 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
/// `trait_ref` would map `T:Trait`.
pub fn get_vtable(
cx: &CodegenCx<'ll, 'tcx>,
pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &Cx,
ty: Ty<'tcx>,
trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> &'ll Value {
let tcx = cx.tcx;
) -> Cx::Value {
let tcx = cx.tcx();
debug!("get_vtable(ty={:?}, trait_ref={:?})", ty, trait_ref);
// 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;
}
......@@ -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
// `get_vtable` in rust_mir/interpret/traits.rs
// /////////////////////////////////////////////////////////////////////////////////////////////
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(align.abi())
].iter().cloned().chain(methods).collect();
......@@ -121,8 +119,8 @@ pub fn get_vtable(
let align = cx.data_layout().pointer_align;
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
}
......@@ -11,7 +11,7 @@
use llvm::{self, BasicBlock};
use rustc::middle::lang_items;
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::interpret::EvalErrorKind;
use abi::{Abi, ArgType, ArgTypeExt, FnType, FnTypeExt, LlvmType, PassMode};
......@@ -57,7 +57,7 @@ fn codegen_terminator(&mut self,
debug!("codegen_terminator: {:?}", terminator);
// Create the cleanup bundle, if needed.
let tcx = bx.tcx();
let tcx = self.cx.tcx;
let span = terminator.source_info.span;
let funclet_bb = self.cleanup_kinds[bb].funclet_bb(bb);
let funclet = funclet_bb.and_then(|funclet_bb| self.funclets[funclet_bb].as_ref());
......
......@@ -16,7 +16,7 @@
use rustc_data_structures::indexed_vec::Idx;
use rustc::mir::interpret::{GlobalId, Pointer, Scalar, Allocation, ConstValue, AllocType};
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 common::{CodegenCx};
use type_of::LayoutLlvmExt;
......
......@@ -13,7 +13,7 @@
use llvm::debuginfo::DIScope;
use llvm_util;
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::ty::subst::Substs;
use rustc::session::config::DebugInfo;
......
......@@ -10,7 +10,7 @@
use llvm::{self, LLVMConstInBoundsGEP};
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::tcx::PlaceTy;
use base;
......
......@@ -10,7 +10,7 @@
use rustc::ty::{self, Ty};
use rustc::ty::cast::{CastTy, IntTy};
use rustc::ty::layout::{self, LayoutOf};
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
use rustc::mir;
use rustc::middle::lang_items::ExchangeMallocFnLangItem;
use rustc_apfloat::{ieee, Float, Status, Round};
......@@ -488,7 +488,7 @@ pub fn codegen_rvalue_operand(
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
assert!(bx.cx().type_is_sized(ty));
let val = bx.cx().const_usize(bx.cx().size_of(ty).bytes());
let tcx = bx.tcx();
let tcx = self.cx.tcx;
(bx, OperandRef {
val: OperandValue::Immediate(val),
layout: self.cx.layout_of(tcx.types.usize),
......
......@@ -15,16 +15,21 @@
use llvm;
use llvm::{Bool, False, True};
use context::CodegenCx;
use interfaces::{BaseTypeMethods, DerivedTypeMethods, TypeMethods};
use interfaces::*;
use value::Value;
use syntax::ast;
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 common::{self, TypeKind};
use type_of::LayoutLlvmExt;
use std::fmt;
use std::cell::RefCell;
use libc::c_uint;
......@@ -42,7 +47,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl BaseTypeMethods for CodegenCx<'ll, 'tcx> {
impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn type_void(&self) -> &'ll Type {
unsafe {
llvm::LLVMVoidTypeInContext(self.llcx)
......@@ -234,6 +239,10 @@ fn int_width(&self, ty: &'ll Type) -> u64 {
fn val_ty(&self, v: &'ll Value) -> &'ll Type {
common::val_ty(v)
}
fn scalar_lltypes(&self) -> &RefCell<FxHashMap<Ty<'tcx>, Self::Type>> {
&self.scalar_lltypes
}
}
impl Type {
......@@ -264,7 +273,7 @@ fn ptr_to(&self) -> &Type {
}
}
impl DerivedTypeMethods for CodegenCx<'ll, 'tcx> {
impl DerivedTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn type_bool(&self) -> &'ll Type {
self.type_i8()
}
......@@ -358,4 +367,8 @@ fn type_padding_filler(
}
}
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)
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册