Generalized base::unsized_info
This commit is contained in:
parent
484e07c231
commit
034f69753b
26 changed files with 338 additions and 287 deletions
|
@ -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,
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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>>
|
||||||
|
{}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
16
src/librustc_codegen_llvm/interfaces/debuginfo.rs
Normal file
16
src/librustc_codegen_llvm/interfaces/debuginfo.rs
Normal 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);
|
||||||
|
}
|
|
@ -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>;
|
|
||||||
}
|
}
|
||||||
|
|
21
src/librustc_codegen_llvm/interfaces/misc.rs
Normal file
21
src/librustc_codegen_llvm/interfaces/misc.rs
Normal 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;
|
||||||
|
}
|
|
@ -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,
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
{}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue