Finish up Type refactoring
This commit is contained in:
parent
57a75374d6
commit
81cf72c264
@ -24,17 +24,17 @@ pub struct Upcalls {
|
||||
|
||||
macro_rules! upcall (
|
||||
(fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
|
||||
let fn_ty = Type::func([ $($arg),* ], $ret);
|
||||
let fn_ty = Type::func([ $($arg),* ], &$ret);
|
||||
base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty)
|
||||
});
|
||||
(nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
|
||||
let fn_ty = Type::func([ $($arg),* ], $ret);
|
||||
let fn_ty = Type::func([ $($arg),* ], &$ret);
|
||||
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
|
||||
base::set_no_unwind(decl);
|
||||
decl
|
||||
});
|
||||
(nothrow fn $name:ident -> $ret:expr) => ({
|
||||
let fn_ty = Type::func([], $ret);
|
||||
let fn_ty = Type::func([], &$ret);
|
||||
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
|
||||
base::set_no_unwind(decl);
|
||||
decl
|
||||
@ -42,7 +42,7 @@ macro_rules! upcall (
|
||||
)
|
||||
|
||||
pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls {
|
||||
let opaque_ptr = Type::i8().to_ptr();
|
||||
let opaque_ptr = Type::i8().ptr_to();
|
||||
let int_ty = Type::int(targ_cfg.arch);
|
||||
|
||||
@Upcalls {
|
||||
|
@ -2141,7 +2141,7 @@ impl TypeNames {
|
||||
}
|
||||
|
||||
pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> {
|
||||
match self.type_names.find(ty.to_ref()) {
|
||||
match self.type_names.find(&ty.to_ref()) {
|
||||
Some(a) => Some(a.slice(0, a.len())),
|
||||
None => None
|
||||
}
|
||||
@ -2151,14 +2151,14 @@ impl TypeNames {
|
||||
self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x))
|
||||
}
|
||||
|
||||
pub fn type_to_str(&self, ty: TypeRef) -> ~str {
|
||||
pub fn type_to_str(&self, ty: Type) -> ~str {
|
||||
match self.find_name(&ty) {
|
||||
option::Some(name) => return name.to_owned(),
|
||||
None => ()
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let kind = llvm::LLVMGetTypeKind(ty);
|
||||
let kind = ty.kind();
|
||||
|
||||
match kind {
|
||||
Void => ~"Void",
|
||||
@ -2172,31 +2172,28 @@ impl TypeNames {
|
||||
Metadata => ~"Metadata",
|
||||
X86_MMX => ~"X86_MMAX",
|
||||
Integer => {
|
||||
fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty) as int)
|
||||
fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int)
|
||||
}
|
||||
Function => {
|
||||
let out_ty = llvm::LLVMGetReturnType(ty);
|
||||
let n_args = llvm::LLVMCountParamTypes(ty) as uint;
|
||||
let args = vec::from_elem(n_args, 0 as TypeRef);
|
||||
llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
|
||||
|
||||
let out_ty = ty.return_type();
|
||||
let args = ty.func_params();
|
||||
let args = args.map(|&ty| self.type_to_str(ty)).connect(", ");
|
||||
let out_ty = self.type_to_str(out_ty);
|
||||
fmt!("fn(%s) -> %s", args, out_ty)
|
||||
}
|
||||
Struct => {
|
||||
let tys = struct_tys(ty);
|
||||
let tys = ty.field_types();
|
||||
let tys = tys.map(|&ty| self.type_to_str(ty)).connect(", ");
|
||||
fmt!("{%s}", tys)
|
||||
}
|
||||
Array => {
|
||||
let el_ty = llvm::LLVMGetElementType(ty);
|
||||
let el_ty = ty.element_type();
|
||||
let el_ty = self.type_to_str(el_ty);
|
||||
let len = llvm::LLVMGetArrayLength(ty) as uint;
|
||||
let len = ty.array_length();
|
||||
fmt!("[%s x %u]", el_ty, len)
|
||||
}
|
||||
Pointer => {
|
||||
let el_ty = llvm::LLVMGetElementType(ty);
|
||||
let el_ty = ty.element_type();
|
||||
let el_ty = self.type_to_str(el_ty);
|
||||
fmt!("*%s", el_ty)
|
||||
}
|
||||
@ -2207,32 +2204,12 @@ impl TypeNames {
|
||||
|
||||
pub fn val_to_str(&self, val: ValueRef) -> ~str {
|
||||
unsafe {
|
||||
self.type_to_str(llvm::LLVMTypeOf(val))
|
||||
let ty = Type::from_ref(llvm::LLVMTypeOf(val));
|
||||
self.type_to_str(ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn float_width(llt: TypeRef) -> uint {
|
||||
unsafe {
|
||||
return match llvm::LLVMGetTypeKind(llt) as int {
|
||||
1 => 32u,
|
||||
2 => 64u,
|
||||
3 => 80u,
|
||||
4 | 5 => 128u,
|
||||
_ => fail!("llvm_float_width called on a non-float type")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] {
|
||||
unsafe {
|
||||
let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint,
|
||||
0 as TypeRef);
|
||||
llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args));
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Memory-managed interface to target data. */
|
||||
|
||||
|
@ -911,7 +911,7 @@ pub fn extract_vec_elems(bcx: block,
|
||||
Sub(bcx, count,
|
||||
C_int(bcx.ccx(), (elem_count - i) as int))])
|
||||
}
|
||||
_ => unsafe { llvm::LLVMGetUndef(vt.llunit_ty) }
|
||||
_ => unsafe { llvm::LLVMGetUndef(vt.llunit_ty.to_ref()) }
|
||||
}
|
||||
};
|
||||
if slice.is_some() {
|
||||
|
@ -59,6 +59,8 @@ use middle::ty;
|
||||
use syntax::ast;
|
||||
use util::ppaux::ty_to_str;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
|
||||
/// Representations.
|
||||
pub enum Repr {
|
||||
@ -260,10 +262,8 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] {
|
||||
let most_aligned = most_aligned.get();
|
||||
let padding = largest_size - most_aligned.size;
|
||||
|
||||
assert!(padding >= 0);
|
||||
|
||||
struct_llfields(cx, most_aligned, sizing)
|
||||
+ [Type::array(Type::i8(), padding /*bad*/as uint)]
|
||||
+ [Type::array(&Type::i8(), padding)]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -439,7 +439,7 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int,
|
||||
// The unit-like case might have a nonzero number of unit-like fields.
|
||||
// (e.g., Result or Either with () as one side.)
|
||||
let ty = type_of::type_of(bcx.ccx(), nullfields[ix]);
|
||||
assert_eq!(machine::llsize_of_alloc(bcx.ccx(), llty), 0);
|
||||
assert_eq!(machine::llsize_of_alloc(bcx.ccx(), ty), 0);
|
||||
// The contents of memory at this pointer can't matter, but use
|
||||
// the value that's "reasonable" in case of pointer comparison.
|
||||
PointerCast(bcx, val, ty.ptr_to())
|
||||
@ -457,7 +457,7 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint,
|
||||
type_of::type_of(ccx, ty)
|
||||
};
|
||||
let real_ty = Type::struct_(fields, st.packed);
|
||||
PointerCast(bcx, val, real_llty.to_ptr().to_ref())
|
||||
PointerCast(bcx, val, real_ty.ptr_to())
|
||||
} else {
|
||||
val
|
||||
};
|
||||
@ -572,7 +572,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef])
|
||||
}
|
||||
|
||||
fn padding(size: u64) -> ValueRef {
|
||||
C_undef(Type::array(Type::i8(), size).to_ref())
|
||||
C_undef(Type::array(&Type::i8(), size))
|
||||
}
|
||||
|
||||
// XXX this utility routine should be somewhere more general
|
||||
|
@ -20,6 +20,8 @@ use middle::trans::callee;
|
||||
use middle::trans::common::*;
|
||||
use middle::ty;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::str;
|
||||
use syntax::ast;
|
||||
|
||||
|
@ -63,6 +63,8 @@ use middle::ty;
|
||||
use util::common::indenter;
|
||||
use util::ppaux::{Repr, ty_to_str};
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::hash;
|
||||
use core::hashmap::{HashMap};
|
||||
use core::int;
|
||||
@ -150,7 +152,7 @@ pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type)
|
||||
}
|
||||
|
||||
pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef {
|
||||
return decl_fn(llmod, name, lib::llvm::CCallConv, llty);
|
||||
return decl_fn(llmod, name, lib::llvm::CCallConv, ty);
|
||||
}
|
||||
|
||||
// Only use this if you are going to actually define the function. It's
|
||||
@ -229,7 +231,7 @@ pub fn opaque_box_body(bcx: block,
|
||||
let _icx = bcx.insn_ctxt("opaque_box_body");
|
||||
let ccx = bcx.ccx();
|
||||
let ty = type_of(ccx, body_t);
|
||||
let ty = Type::box(ccx, ty);
|
||||
let ty = Type::box(ccx, &ty);
|
||||
let boxptr = PointerCast(bcx, boxptr, ty.ptr_to());
|
||||
GEPi(bcx, boxptr, [0u, abi::box_field_body])
|
||||
}
|
||||
@ -281,15 +283,8 @@ pub fn malloc_raw_dyn(bcx: block,
|
||||
* address space 0. Otherwise the resulting (non-box) pointer will be in the
|
||||
* wrong address space and thus be the wrong type.
|
||||
*/
|
||||
pub fn non_gc_box_cast(bcx: block, val: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
debug!("non_gc_box_cast");
|
||||
add_comment(bcx, "non_gc_box_cast");
|
||||
assert!(llvm::LLVMGetPointerAddressSpace(val_ty(val)) ==
|
||||
gc_box_addrspace || bcx.unreachable);
|
||||
let non_gc_t = llvm::LLVMGetElementType(val_ty(val)).ptr_to();
|
||||
PointerCast(bcx, val, non_gc_t)
|
||||
}
|
||||
pub fn non_gc_box_cast(_: block, val: ValueRef) -> ValueRef {
|
||||
val
|
||||
}
|
||||
|
||||
// malloc_raw: expects an unboxed type and returns a pointer to
|
||||
@ -721,8 +716,8 @@ pub fn cast_shift_expr_rhs(cx: block, op: ast::binop,
|
||||
pub fn cast_shift_const_rhs(op: ast::binop,
|
||||
lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
cast_shift_rhs(op, lhs, rhs,
|
||||
|a, b| unsafe { llvm::LLVMConstTrunc(a, b) },
|
||||
|a, b| unsafe { llvm::LLVMConstZExt(a, b) })
|
||||
|a, b| unsafe { llvm::LLVMConstTrunc(a, b.to_ref()) },
|
||||
|a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) })
|
||||
}
|
||||
|
||||
pub fn cast_shift_rhs(op: ast::binop,
|
||||
@ -735,8 +730,8 @@ pub fn cast_shift_rhs(op: ast::binop,
|
||||
if ast_util::is_shift_binop(op) {
|
||||
let rhs_llty = val_ty(rhs);
|
||||
let lhs_llty = val_ty(lhs);
|
||||
let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty);
|
||||
let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty);
|
||||
let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty.to_ref());
|
||||
let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty.to_ref());
|
||||
if lhs_sz < rhs_sz {
|
||||
trunc(rhs, lhs_llty)
|
||||
} else if lhs_sz > rhs_sz {
|
||||
@ -761,11 +756,11 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop,
|
||||
};
|
||||
let is_zero = match ty::get(rhs_t).sty {
|
||||
ty::ty_int(t) => {
|
||||
let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, False);
|
||||
let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
|
||||
ICmp(cx, lib::llvm::IntEQ, rhs, zero)
|
||||
}
|
||||
ty::ty_uint(t) => {
|
||||
let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, False);
|
||||
let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
|
||||
ICmp(cx, lib::llvm::IntEQ, rhs, zero)
|
||||
}
|
||||
_ => {
|
||||
@ -779,7 +774,7 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop,
|
||||
}
|
||||
|
||||
pub fn null_env_ptr(bcx: block) -> ValueRef {
|
||||
C_null(Type::opaque_box(bcx.ccx()).to_ptr())
|
||||
C_null(Type::opaque_box(bcx.ccx()).ptr_to())
|
||||
}
|
||||
|
||||
pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t)
|
||||
@ -1479,7 +1474,7 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) {
|
||||
let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key);
|
||||
let llptr = PointerCast(cx, llptr, Type::i8().ptr_to());
|
||||
let llzeroval = C_u8(0);
|
||||
let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type.to_ref());
|
||||
let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type);
|
||||
let align = C_i32(llalign_of_min(ccx, ty) as i32);
|
||||
let volatile = C_i1(false);
|
||||
Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
|
||||
@ -1506,7 +1501,7 @@ pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef {
|
||||
}
|
||||
}
|
||||
let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas);
|
||||
let p = Alloca(initcx, ty.to_ref());
|
||||
let p = Alloca(initcx, ty);
|
||||
if zero { memzero(initcx, p, ty); }
|
||||
p
|
||||
}
|
||||
@ -1515,10 +1510,10 @@ pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef {
|
||||
let _icx = cx.insn_ctxt("arrayalloca");
|
||||
if cx.unreachable {
|
||||
unsafe {
|
||||
return llvm::LLVMGetUndef(ty);
|
||||
return llvm::LLVMGetUndef(ty.to_ref());
|
||||
}
|
||||
}
|
||||
return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty.to_ref(), v);
|
||||
return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty, v);
|
||||
}
|
||||
|
||||
pub struct BasicBlocks {
|
||||
@ -1588,7 +1583,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
|
||||
let fcx = @mut fn_ctxt_ {
|
||||
llfn: llfndecl,
|
||||
llenv: unsafe {
|
||||
llvm::LLVMGetUndef(Type::i8p())
|
||||
llvm::LLVMGetUndef(Type::i8p().to_ref())
|
||||
},
|
||||
llretptr: None,
|
||||
llstaticallocas: llbbs.sa,
|
||||
@ -2309,7 +2304,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
|
||||
fn create_entry_fn(ccx: @mut CrateContext,
|
||||
rust_main: ValueRef,
|
||||
use_start_lang_item: bool) {
|
||||
let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()], ccx.int_type);
|
||||
let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()], &ccx.int_type);
|
||||
|
||||
// FIXME #4404 android JNI hacks
|
||||
let llfn = if *ccx.sess.building_library {
|
||||
@ -2338,10 +2333,9 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
|
||||
}
|
||||
|
||||
let crate_map = ccx.crate_map;
|
||||
let opaque_crate_map = llvm::LLVMBuildPointerCast(bld,
|
||||
crate_map,
|
||||
Type::i8p(),
|
||||
noname());
|
||||
let opaque_crate_map = do "crate_map".as_c_str |buf| {
|
||||
llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
|
||||
};
|
||||
|
||||
let (start_fn, args) = if use_start_lang_item {
|
||||
let start_def_id = ccx.tcx.lang_items.start_fn();
|
||||
@ -2354,8 +2348,9 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
|
||||
};
|
||||
|
||||
let args = {
|
||||
let opaque_rust_main = llvm::LLVMBuildPointerCast(
|
||||
bld, rust_main, Type::i8p(), noname());
|
||||
let opaque_rust_main = do "rust_main".as_c_str |buf| {
|
||||
llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p().to_ref(), buf)
|
||||
};
|
||||
|
||||
~[
|
||||
C_null(Type::opaque_box(ccx).ptr_to()),
|
||||
@ -2487,7 +2482,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
||||
let g = do str::as_c_str(ident) |buf| {
|
||||
unsafe {
|
||||
let ty = type_of(ccx, typ);
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ty, buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
|
||||
}
|
||||
};
|
||||
g
|
||||
@ -2583,7 +2578,7 @@ pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) {
|
||||
note_unique_llvm_symbol(ccx, s);
|
||||
let discrim_gvar = str::as_c_str(s, |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
|
||||
}
|
||||
});
|
||||
unsafe {
|
||||
@ -2616,14 +2611,14 @@ pub fn vp2i(cx: block, v: ValueRef) -> ValueRef {
|
||||
|
||||
pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
return llvm::LLVMConstPtrToInt(v, ccx.int_type);
|
||||
return llvm::LLVMConstPtrToInt(v, ccx.int_type.to_ref());
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! ifn (
|
||||
($name:expr, $args:expr, $ret:expr) => ({
|
||||
let name = $name;
|
||||
let f = decl_cdecl_fn(llmod, name, Type::func($args, $ret));
|
||||
let f = decl_cdecl_fn(llmod, name, Type::func($args, &$ret));
|
||||
intrinsics.insert(name, f);
|
||||
})
|
||||
)
|
||||
@ -2642,7 +2637,7 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> {
|
||||
[i8p, i8p, Type::i64(), Type::i32(), Type::i1()], Type::void());
|
||||
ifn!("llvm.memset.p0i8.i32",
|
||||
[i8p, Type::i8(), Type::i32(), Type::i32(), Type::i1()], Type::void());
|
||||
ifn!("llvm.memcpy.p0i8.i64",
|
||||
ifn!("llvm.memset.p0i8.i64",
|
||||
[i8p, Type::i8(), Type::i64(), Type::i32(), Type::i1()], Type::void());
|
||||
|
||||
ifn!("llvm.trap", [], Type::void());
|
||||
@ -2710,7 +2705,7 @@ pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'stati
|
||||
}
|
||||
|
||||
pub fn trap(bcx: block) {
|
||||
match bcx.ccx().intrinsics.find_equiv("llvm.trap") {
|
||||
match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") {
|
||||
Some(&x) => { Call(bcx, x, []); },
|
||||
_ => bcx.sess().bug("unbound llvm.trap in trap")
|
||||
}
|
||||
@ -2724,7 +2719,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
|
||||
let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id;
|
||||
let gc_metadata = do str::as_c_str(gc_metadata_name) |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, Type::i32(), buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
|
||||
}
|
||||
};
|
||||
unsafe {
|
||||
@ -2736,12 +2731,12 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
|
||||
|
||||
pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
|
||||
let elttype = Type::struct_([ccx.int_type, ccx.int_type], false);
|
||||
let maptype = Type::array(elttype, ccx.module_data.len() + 1);
|
||||
let map = str::as_c_str("_rust_mod_map", |buf| {
|
||||
let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64);
|
||||
let map = do "_rust_mod_map".as_c_str |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, maptype, buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
|
||||
}
|
||||
});
|
||||
};
|
||||
lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage);
|
||||
let mut elts: ~[ValueRef] = ~[];
|
||||
|
||||
@ -2783,11 +2778,11 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
|
||||
~"toplevel"
|
||||
};
|
||||
let sym_name = ~"_rust_crate_map_" + mapname;
|
||||
let arrtype = Type::array(int_type, n_subcrates as u64);
|
||||
let arrtype = Type::array(&int_type, n_subcrates as u64);
|
||||
let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false);
|
||||
let map = str::as_c_str(sym_name, |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(llmod, maptype, buf)
|
||||
llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
|
||||
}
|
||||
});
|
||||
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
|
||||
@ -2806,7 +2801,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
|
||||
cstore::get_crate_hash(cstore, i));
|
||||
let cr = str::as_c_str(nm, |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
|
||||
}
|
||||
});
|
||||
subcrates.push(p2i(ccx, cr));
|
||||
@ -2830,8 +2825,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
|
||||
let mod_map = create_module_map(ccx);
|
||||
llvm::LLVMSetInitializer(map, C_struct(
|
||||
[C_i32(1),
|
||||
lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn,
|
||||
Type::i8p()),
|
||||
lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, Type::i8p().to_ref()),
|
||||
p2i(ccx, mod_map),
|
||||
C_array(ccx.int_type, subcrates)]));
|
||||
}
|
||||
@ -2869,7 +2863,7 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) {
|
||||
let llconst = C_struct([llmeta]);
|
||||
let mut llglobal = str::as_c_str("rust_metadata", |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf)
|
||||
llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf)
|
||||
}
|
||||
});
|
||||
unsafe {
|
||||
@ -2880,9 +2874,9 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) {
|
||||
lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
|
||||
|
||||
let t_ptr_i8 = Type::i8p();
|
||||
llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8);
|
||||
llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8.to_ref());
|
||||
let llvm_used = do "llvm.used".as_c_str |buf| {
|
||||
llvm::LLVMAddGlobal(cx.llmod, Type::array(t_ptr_i8, 1u), buf)
|
||||
llvm::LLVMAddGlobal(cx.llmod, Type::array(&t_ptr_i8, 1).to_ref(), buf)
|
||||
};
|
||||
lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
|
||||
llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, [llglobal]));
|
||||
|
@ -13,12 +13,14 @@ use core::prelude::*;
|
||||
use lib::llvm::llvm;
|
||||
use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
|
||||
use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
|
||||
use lib::llvm::{ValueRef, Type, BasicBlockRef, BuilderRef, ModuleRef};
|
||||
use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
|
||||
use lib;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::machine::llalign_of_min;
|
||||
use syntax::codemap::span;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::cast;
|
||||
use core::hashmap::HashMap;
|
||||
use core::libc::{c_uint, c_ulonglong, c_char};
|
||||
@ -232,7 +234,7 @@ pub fn Unreachable(cx: block) {
|
||||
|
||||
pub fn _Undef(val: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
return llvm::LLVMGetUndef(val_ty(val));
|
||||
return llvm::LLVMGetUndef(val_ty(val).to_ref());
|
||||
}
|
||||
}
|
||||
|
||||
@ -504,7 +506,7 @@ pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef {
|
||||
|
||||
pub fn Alloca(cx: block, Ty: Type) -> ValueRef {
|
||||
unsafe {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); }
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
|
||||
count_insn(cx, "alloca");
|
||||
return llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname());
|
||||
}
|
||||
@ -512,7 +514,7 @@ pub fn Alloca(cx: block, Ty: Type) -> ValueRef {
|
||||
|
||||
pub fn ArrayAlloca(cx: block, Ty: Type, Val: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); }
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
|
||||
count_insn(cx, "arrayalloca");
|
||||
return llvm::LLVMBuildArrayAlloca(B(cx), Ty.to_ref(), Val, noname());
|
||||
}
|
||||
@ -531,9 +533,12 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
|
||||
let ccx = cx.fcx.ccx;
|
||||
if cx.unreachable {
|
||||
let ty = val_ty(PointerVal);
|
||||
let eltty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Array {
|
||||
llvm::LLVMGetElementType(ty) } else { ccx.int_type };
|
||||
return llvm::LLVMGetUndef(eltty);
|
||||
let eltty = if ty.kind() == lib::llvm::Array {
|
||||
ty.element_type()
|
||||
} else {
|
||||
ccx.int_type
|
||||
};
|
||||
return llvm::LLVMGetUndef(eltty.to_ref());
|
||||
}
|
||||
count_insn(cx, "load");
|
||||
return llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
|
||||
@ -544,7 +549,7 @@ pub fn AtomicLoad(cx: block, PointerVal: ValueRef, order: AtomicOrdering) -> Val
|
||||
unsafe {
|
||||
let ccx = cx.fcx.ccx;
|
||||
if cx.unreachable {
|
||||
return llvm::LLVMGetUndef(ccx.int_type);
|
||||
return llvm::LLVMGetUndef(ccx.int_type.to_ref());
|
||||
}
|
||||
count_insn(cx, "load.atomic");
|
||||
let align = llalign_of_min(ccx, ccx.int_type);
|
||||
@ -639,7 +644,7 @@ pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef {
|
||||
|
||||
pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef {
|
||||
unsafe {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p()); }
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
|
||||
count_insn(cx, "globalstring");
|
||||
return llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
|
||||
}
|
||||
@ -647,7 +652,7 @@ pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef {
|
||||
|
||||
pub fn GlobalStringPtr(cx: block, _Str: *c_char) -> ValueRef {
|
||||
unsafe {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p()); }
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
|
||||
count_insn(cx, "globalstringptr");
|
||||
return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
|
||||
}
|
||||
@ -841,7 +846,7 @@ pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef])
|
||||
unsafe {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); }
|
||||
assert_eq!(vals.len(), bbs.len());
|
||||
let phi = EmptyPhi(cx, Ty.to_ref());
|
||||
let phi = EmptyPhi(cx, Ty);
|
||||
count_insn(cx, "addincoming");
|
||||
llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals),
|
||||
vec::raw::to_ptr(bbs),
|
||||
@ -863,10 +868,13 @@ pub fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
let ccx = cx.fcx.ccx;
|
||||
let ty = val_ty(Fn);
|
||||
let retty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Integer {
|
||||
llvm::LLVMGetReturnType(ty) } else { ccx.int_type };
|
||||
count_insn(cx, "");
|
||||
return llvm::LLVMGetUndef(retty);
|
||||
let retty = if ty.kind() == lib::llvm::Integer {
|
||||
ty.return_type()
|
||||
} else {
|
||||
ccx.int_type
|
||||
};
|
||||
count_insn(cx, "ret_undef");
|
||||
return llvm::LLVMGetUndef(retty.to_ref());
|
||||
}
|
||||
}
|
||||
|
||||
@ -887,9 +895,10 @@ pub fn add_comment(bcx: block, text: &str) {
|
||||
let comment_text = ~"# " +
|
||||
sanitized.replace("\n", "\n\t# ");
|
||||
count_insn(bcx, "inlineasm");
|
||||
let asm = str::as_c_str(comment_text, |c| {
|
||||
llvm::LLVMConstInlineAsm(Type::func([], Type::void()), c, noname(), False, False)
|
||||
});
|
||||
let asm = do comment_text.as_c_str |c| {
|
||||
llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(),
|
||||
c, noname(), False, False)
|
||||
};
|
||||
Call(bcx, asm, []);
|
||||
}
|
||||
}
|
||||
@ -913,8 +922,8 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
|
||||
};
|
||||
|
||||
debug!("Asm Output Type: %?", cx.ccx().tn.type_to_str(output));
|
||||
let fty = Type::func(argtys, output);
|
||||
let v = llvm::LLVMInlineAsm(llfty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
|
||||
let fty = Type::func(argtys, &output);
|
||||
let v = llvm::LLVMInlineAsm(fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
|
||||
|
||||
Call(cx, v, inputs)
|
||||
}
|
||||
@ -1005,9 +1014,9 @@ pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
|
||||
pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
let elt_ty = val_ty(EltVal);
|
||||
let Undef = llvm::LLVMGetUndef(Type::vector(elt_ty, NumElts).to_ref());
|
||||
let Undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, NumElts as u64).to_ref());
|
||||
let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0));
|
||||
ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(Type::i32().to_ref(), NumElts)))
|
||||
ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(&Type::i32(), NumElts as u64)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1049,7 +1058,7 @@ pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef {
|
||||
pub fn PtrDiff(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
let ccx = cx.fcx.ccx;
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type); }
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type.to_ref()); }
|
||||
count_insn(cx, "ptrdiff");
|
||||
return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
@ -8,20 +8,19 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use lib::llvm::{llvm, TypeRef, ValueRef, Attribute, Void};
|
||||
use lib::llvm::{llvm, ValueRef, Attribute, Void};
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::build::*;
|
||||
use middle::trans::common::*;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::libc::c_uint;
|
||||
use core::option;
|
||||
use core::vec;
|
||||
|
||||
pub trait ABIInfo {
|
||||
fn compute_info(&self,
|
||||
atys: &[TypeRef],
|
||||
rty: TypeRef,
|
||||
ret_def: bool) -> FnType;
|
||||
fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType;
|
||||
}
|
||||
|
||||
pub struct LLVMType {
|
||||
@ -40,7 +39,7 @@ impl FnType {
|
||||
pub fn decl_fn(&self, decl: &fn(fnty: Type) -> ValueRef) -> ValueRef {
|
||||
let atys = vec::map(self.arg_tys, |t| t.ty);
|
||||
let rty = self.ret_ty.ty;
|
||||
let fnty = Type::func(atys, rty);
|
||||
let fnty = Type::func(atys, &rty);
|
||||
let llfn = decl(fnty);
|
||||
|
||||
for self.attrs.iter().enumerate().advance |(i, a)| {
|
||||
@ -57,10 +56,7 @@ impl FnType {
|
||||
return llfn;
|
||||
}
|
||||
|
||||
pub fn build_shim_args(&self,
|
||||
bcx: block,
|
||||
arg_tys: &[Type],
|
||||
llargbundle: ValueRef)
|
||||
pub fn build_shim_args(&self, bcx: block, arg_tys: &[Type], llargbundle: ValueRef)
|
||||
-> ~[ValueRef] {
|
||||
let mut atys: &[LLVMType] = self.arg_tys;
|
||||
let mut attrs: &[option::Option<Attribute>] = self.attrs;
|
||||
@ -80,7 +76,7 @@ impl FnType {
|
||||
while i < n {
|
||||
let llargval = if atys[i].cast {
|
||||
let arg_ptr = GEPi(bcx, llargbundle, [0u, i]);
|
||||
let arg_ptr = BitCast(bcx, arg_ptr, T_ptr(atys[i].ty));
|
||||
let arg_ptr = BitCast(bcx, arg_ptr, atys[i].ty.ptr_to());
|
||||
Load(bcx, arg_ptr)
|
||||
} else if attrs[i].is_some() {
|
||||
GEPi(bcx, llargbundle, [0u, i])
|
||||
@ -94,19 +90,14 @@ impl FnType {
|
||||
return llargvals;
|
||||
}
|
||||
|
||||
pub fn build_shim_ret(&self,
|
||||
bcx: block,
|
||||
arg_tys: &[Type],
|
||||
ret_def: bool,
|
||||
llargbundle: ValueRef,
|
||||
llretval: ValueRef) {
|
||||
pub fn build_shim_ret(&self, bcx: block, arg_tys: &[Type], ret_def: bool,
|
||||
llargbundle: ValueRef, llretval: ValueRef) {
|
||||
for vec::eachi(self.attrs) |i, a| {
|
||||
for self.attrs.iter().enumerate().advance |(i, a)| {
|
||||
match *a {
|
||||
option::Some(attr) => {
|
||||
unsafe {
|
||||
llvm::LLVMAddInstrAttribute(llretval,
|
||||
(i + 1u) as c_uint,
|
||||
attr as c_uint);
|
||||
llvm::LLVMAddInstrAttribute(llretval, (i + 1u) as c_uint, attr as c_uint);
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
@ -121,7 +112,7 @@ impl FnType {
|
||||
// R* llretloc = *llretptr; /* (args->r) */
|
||||
let llretloc = Load(bcx, llretptr);
|
||||
if self.ret_ty.cast {
|
||||
let tmp_ptr = BitCast(bcx, llretloc, T_ptr(self.ret_ty.ty));
|
||||
let tmp_ptr = BitCast(bcx, llretloc, self.ret_ty.ty.ptr_to());
|
||||
// *args->r = r;
|
||||
Store(bcx, llretval, tmp_ptr);
|
||||
} else {
|
||||
@ -130,11 +121,8 @@ impl FnType {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn build_wrap_args(&self,
|
||||
bcx: block,
|
||||
ret_ty: Type,
|
||||
llwrapfn: ValueRef,
|
||||
llargbundle: ValueRef) {
|
||||
pub fn build_wrap_args(&self, bcx: block, ret_ty: Type,
|
||||
llwrapfn: ValueRef, llargbundle: ValueRef) {
|
||||
let mut atys: &[LLVMType] = self.arg_tys;
|
||||
let mut attrs: &[option::Option<Attribute>] = self.attrs;
|
||||
let mut j = 0u;
|
||||
@ -159,7 +147,7 @@ impl FnType {
|
||||
store_inbounds(bcx, argval, llargbundle, [0u, i]);
|
||||
} else if atys[i].cast {
|
||||
let argptr = GEPi(bcx, llargbundle, [0u, i]);
|
||||
let argptr = BitCast(bcx, argptr, T_ptr(atys[i].ty));
|
||||
let argptr = BitCast(bcx, argptr, atys[i].ty.ptr_to());
|
||||
Store(bcx, argval, argptr);
|
||||
} else {
|
||||
store_inbounds(bcx, argval, llargbundle, [0u, i]);
|
||||
@ -169,14 +157,9 @@ impl FnType {
|
||||
store_inbounds(bcx, llretptr, llargbundle, [0u, n]);
|
||||
}
|
||||
|
||||
pub fn build_wrap_ret(&self,
|
||||
bcx: block,
|
||||
arg_tys: &[TypeRef],
|
||||
llargbundle: ValueRef) {
|
||||
unsafe {
|
||||
if llvm::LLVMGetTypeKind(self.ret_ty.ty) == Void {
|
||||
return;
|
||||
}
|
||||
pub fn build_wrap_ret(&self, bcx: block, arg_tys: &[Type], llargbundle: ValueRef) {
|
||||
if self.ret_ty.ty.kind() == Void {
|
||||
return;
|
||||
}
|
||||
|
||||
if bcx.fcx.llretptr.is_some() {
|
||||
@ -187,9 +170,7 @@ impl FnType {
|
||||
} else {
|
||||
Load(bcx, llretval)
|
||||
};
|
||||
let llretptr = BitCast(bcx,
|
||||
bcx.fcx.llretptr.get(),
|
||||
self.ret_ty.ty.ptr_to());
|
||||
let llretptr = BitCast(bcx, bcx.fcx.llretptr.get(), self.ret_ty.ty.ptr_to());
|
||||
Store(bcx, llretval, llretptr);
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,12 @@
|
||||
// except according to those terms.
|
||||
|
||||
use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
|
||||
use lib::llvm::struct_tys;
|
||||
use lib::llvm::{Attribute, StructRetAttribute};
|
||||
use lib::llvm::True;
|
||||
use middle::trans::cabi::{ABIInfo, FnType, LLVMType};
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::option::{Option, None, Some};
|
||||
use core::uint;
|
||||
|
||||
@ -27,58 +28,58 @@ fn align(off: uint, ty: Type) -> uint {
|
||||
}
|
||||
|
||||
fn ty_align(ty: Type) -> uint {
|
||||
unsafe {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
1
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t)))
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let elt = ty.element_type();
|
||||
ty_align(elt)
|
||||
}
|
||||
_ => fail!("ty_align: unhandled type")
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
1
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t)))
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let elt = ty.element_type();
|
||||
ty_align(elt)
|
||||
}
|
||||
_ => fail!("ty_align: unhandled type")
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_size(ty: Type) -> uint {
|
||||
unsafe {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
|
||||
align(size, ty)
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let len = ty.array_length();
|
||||
let elt = ty.element_type();
|
||||
let eltsz = ty_size(elt);
|
||||
len * eltsz
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
|
||||
align(size, ty)
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let len = ty.array_length();
|
||||
let elt = ty.element_type();
|
||||
let eltsz = ty_size(elt);
|
||||
len * eltsz
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,9 +108,9 @@ fn classify_arg_ty(ty: Type) -> (LLVMType, Option<Attribute>) {
|
||||
let align = ty_align(ty);
|
||||
let size = ty_size(ty);
|
||||
let llty = if align <= 4 {
|
||||
Type::array(Type::i32(), (size + 3) / 4)
|
||||
Type::array(&Type::i32(), (size + 3) / 4 as u64)
|
||||
} else {
|
||||
Type::array(Type::i64(), (size + 7) / 8)
|
||||
Type::array(&Type::i64(), (size + 7) / 8 as u64)
|
||||
};
|
||||
(LLVMType { cast: true, ty: llty }, None)
|
||||
}
|
||||
@ -122,7 +123,7 @@ fn is_reg_ty(ty: Type) -> bool {
|
||||
| Float
|
||||
| Double => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,13 +15,14 @@ use core::ptr;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
|
||||
use lib::llvm::struct_tys;
|
||||
use lib::llvm::{Attribute, StructRetAttribute};
|
||||
use lib::llvm::True;
|
||||
use middle::trans::context::task_llcx;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::cabi::*;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
fn align_up_to(off: uint, a: uint) -> uint {
|
||||
return (off + a - 1u) / a * a;
|
||||
}
|
||||
@ -32,58 +33,58 @@ fn align(off: uint, ty: Type) -> uint {
|
||||
}
|
||||
|
||||
fn ty_align(ty: Type) -> uint {
|
||||
unsafe {
|
||||
return match llvm::LLVMGetTypeKind(ty) {
|
||||
Integer => {
|
||||
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
1
|
||||
} else {
|
||||
let str_tys = struct_tys(ty);
|
||||
str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t)))
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let elt = llvm::LLVMGetElementType(ty);
|
||||
ty_align(elt)
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
};
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
1
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t)))
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let elt = ty.element_type();
|
||||
ty_align(elt)
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_size(ty: TypeRef) -> uint {
|
||||
unsafe {
|
||||
return match llvm::LLVMGetTypeKind(ty) {
|
||||
Integer => {
|
||||
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
|
||||
fn ty_size(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if llvm::LLVMIsPackedStruct(ty) == True {
|
||||
let str_tys = struct_tys(ty);
|
||||
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
|
||||
align(size, ty)
|
||||
}
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
|
||||
align(size, ty)
|
||||
}
|
||||
Array => {
|
||||
let len = ty.array_length();
|
||||
let elt = ty.element_type();
|
||||
let eltsz = ty_size(elt);
|
||||
len * eltsz
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
};
|
||||
}
|
||||
Array => {
|
||||
let len = ty.array_length();
|
||||
let elt = ty.element_type();
|
||||
let eltsz = ty_size(elt);
|
||||
len * eltsz
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +121,7 @@ fn classify_arg_ty(ty: Type, offset: &mut uint) -> (LLVMType, Option<Attribute>)
|
||||
};
|
||||
}
|
||||
|
||||
fn is_reg_ty(ty: TypeRef) -> bool {
|
||||
fn is_reg_ty(ty: Type) -> bool {
|
||||
unsafe {
|
||||
return match ty.kind() {
|
||||
Integer
|
||||
@ -153,11 +154,11 @@ fn coerce_to_int(size: uint) -> ~[Type] {
|
||||
let r = size % 32;
|
||||
if r > 0 {
|
||||
unsafe {
|
||||
Type::from_ref(args.push(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint)))
|
||||
args.push(Type::from_ref(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint)));
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
args
|
||||
}
|
||||
|
||||
fn struct_ty(ty: Type,
|
||||
|
@ -17,6 +17,8 @@ use super::cabi::*;
|
||||
use super::common::*;
|
||||
use super::machine::*;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
struct X86_ABIInfo {
|
||||
ccx: @mut CrateContext
|
||||
}
|
||||
|
@ -11,14 +11,15 @@
|
||||
// The classification code for the x86_64 ABI is taken from the clay language
|
||||
// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
|
||||
|
||||
use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double};
|
||||
use lib::llvm::{llvm, Integer, Pointer, Float, Double};
|
||||
use lib::llvm::{Struct, Array, Attribute};
|
||||
use lib::llvm::{StructRetAttribute, ByValAttribute};
|
||||
use lib::llvm::struct_tys;
|
||||
use lib::llvm::True;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::cabi::*;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::libc::c_uint;
|
||||
use core::option;
|
||||
use core::option::Option;
|
||||
@ -28,7 +29,7 @@ use core::vec;
|
||||
#[deriving(Eq)]
|
||||
enum RegClass {
|
||||
NoClass,
|
||||
Integer,
|
||||
Int,
|
||||
SSEFs,
|
||||
SSEFv,
|
||||
SSEDs,
|
||||
@ -43,7 +44,7 @@ enum RegClass {
|
||||
|
||||
impl Type {
|
||||
fn is_reg_ty(&self) -> bool {
|
||||
match ty.kind() {
|
||||
match self.kind() {
|
||||
Integer | Pointer | Float | Double => true,
|
||||
_ => false
|
||||
}
|
||||
@ -59,6 +60,11 @@ impl RegClass {
|
||||
}
|
||||
}
|
||||
|
||||
trait ClassList {
|
||||
fn is_pass_byval(&self) -> bool;
|
||||
fn is_ret_bysret(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<'self> ClassList for &'self [RegClass] {
|
||||
fn is_pass_byval(&self) -> bool {
|
||||
if self.len() == 0 { return false; }
|
||||
@ -83,64 +89,64 @@ fn classify_ty(ty: Type) -> ~[RegClass] {
|
||||
}
|
||||
|
||||
fn ty_align(ty: Type) -> uint {
|
||||
unsafe {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
Pointer => 8,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
1
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t)))
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let elt = ty.element_type();
|
||||
ty_align(elt)
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
};
|
||||
}
|
||||
Pointer => 8,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
1
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t)))
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let elt = ty.element_type();
|
||||
ty_align(elt)
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_size(ty: TypeRef) -> uint {
|
||||
unsafe {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
|
||||
fn ty_size(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
Pointer => 8,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
|
||||
align(size, ty)
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let len = ty.array_length();
|
||||
let elt = ty.element_type();
|
||||
let eltsz = ty_size(elt);
|
||||
len * eltsz
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
}
|
||||
Pointer => 8,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
|
||||
align(size, ty)
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let len = ty.array_length();
|
||||
let elt = ty.element_type();
|
||||
let eltsz = ty_size(elt);
|
||||
len * eltsz
|
||||
}
|
||||
_ => fail!("ty_size: unhandled type")
|
||||
}
|
||||
}
|
||||
|
||||
fn all_mem(cls: &mut [RegClass]) {
|
||||
for uint::range(0, cls.len()) |i| {
|
||||
cls[i] = memory_class;
|
||||
cls[i] = Memory;
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,21 +155,21 @@ fn classify_ty(ty: Type) -> ~[RegClass] {
|
||||
newv: RegClass) {
|
||||
if cls[i] == newv {
|
||||
return;
|
||||
} else if cls[i] == no_class {
|
||||
} else if cls[i] == NoClass {
|
||||
cls[i] = newv;
|
||||
} else if newv == no_class {
|
||||
} else if newv == NoClass {
|
||||
return;
|
||||
} else if cls[i] == memory_class || newv == memory_class {
|
||||
cls[i] = memory_class;
|
||||
} else if cls[i] == integer_class || newv == integer_class {
|
||||
cls[i] = integer_class;
|
||||
} else if cls[i] == x87_class ||
|
||||
cls[i] == x87up_class ||
|
||||
cls[i] == complex_x87_class ||
|
||||
newv == x87_class ||
|
||||
newv == x87up_class ||
|
||||
newv == complex_x87_class {
|
||||
cls[i] = memory_class;
|
||||
} else if cls[i] == Memory || newv == Memory {
|
||||
cls[i] = Memory;
|
||||
} else if cls[i] == Int || newv == Int {
|
||||
cls[i] = Int;
|
||||
} else if cls[i] == X87 ||
|
||||
cls[i] == X87Up ||
|
||||
cls[i] == ComplexX87 ||
|
||||
newv == X87 ||
|
||||
newv == X87Up ||
|
||||
newv == ComplexX87 {
|
||||
cls[i] = Memory;
|
||||
} else {
|
||||
cls[i] = newv;
|
||||
}
|
||||
@ -192,7 +198,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] {
|
||||
let mut i = off / 8u;
|
||||
let e = (off + t_size + 7u) / 8u;
|
||||
while i < e {
|
||||
unify(cls, ix + i, memory_class);
|
||||
unify(cls, ix + i, Memory);
|
||||
i += 1u;
|
||||
}
|
||||
return;
|
||||
@ -201,17 +207,17 @@ fn classify_ty(ty: Type) -> ~[RegClass] {
|
||||
match ty.kind() {
|
||||
Integer |
|
||||
Pointer => {
|
||||
unify(cls, ix + off / 8u, integer_class);
|
||||
unify(cls, ix + off / 8u, Int);
|
||||
}
|
||||
Float => {
|
||||
if off % 8u == 4u {
|
||||
unify(cls, ix + off / 8u, sse_fv_class);
|
||||
unify(cls, ix + off / 8u, SSEFv);
|
||||
} else {
|
||||
unify(cls, ix + off / 8u, sse_fs_class);
|
||||
unify(cls, ix + off / 8u, SSEFs);
|
||||
}
|
||||
}
|
||||
Double => {
|
||||
unify(cls, ix + off / 8u, sse_ds_class);
|
||||
unify(cls, ix + off / 8u, SSEDs);
|
||||
}
|
||||
Struct => {
|
||||
classify_struct(ty.field_types(), cls, ix, off);
|
||||
@ -242,7 +248,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] {
|
||||
if cls[i].is_sse() {
|
||||
i += 1u;
|
||||
while i < e {
|
||||
if cls[i] != sseup_class {
|
||||
if cls[i] != SSEUp {
|
||||
all_mem(cls);
|
||||
return;
|
||||
}
|
||||
@ -254,24 +260,24 @@ fn classify_ty(ty: Type) -> ~[RegClass] {
|
||||
}
|
||||
} else {
|
||||
while i < e {
|
||||
if cls[i] == memory_class {
|
||||
if cls[i] == Memory {
|
||||
all_mem(cls);
|
||||
return;
|
||||
}
|
||||
if cls[i] == x87up_class {
|
||||
if cls[i] == X87Up {
|
||||
// for darwin
|
||||
// cls[i] = sse_ds_class;
|
||||
// cls[i] = SSEDs;
|
||||
all_mem(cls);
|
||||
return;
|
||||
}
|
||||
if cls[i] == sseup_class {
|
||||
cls[i] = sse_int_class;
|
||||
if cls[i] == SSEUp {
|
||||
cls[i] = SSEInt;
|
||||
} else if cls[i].is_sse() {
|
||||
i += 1;
|
||||
while i != e && cls[i] == sseup_class { i += 1u; }
|
||||
} else if cls[i] == x87_class {
|
||||
while i != e && cls[i] == SSEUp { i += 1u; }
|
||||
} else if cls[i] == X87 {
|
||||
i += 1;
|
||||
while i != e && cls[i] == x87up_class { i += 1u; }
|
||||
while i != e && cls[i] == X87Up { i += 1u; }
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
@ -281,7 +287,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] {
|
||||
}
|
||||
|
||||
let words = (ty_size(ty) + 7) / 8;
|
||||
let mut cls = vec::from_elem(words, no_class);
|
||||
let mut cls = vec::from_elem(words, NoClass);
|
||||
if words > 4 {
|
||||
all_mem(cls);
|
||||
let cls = cls;
|
||||
@ -296,7 +302,7 @@ fn llreg_ty(cls: &[RegClass]) -> Type {
|
||||
fn llvec_len(cls: &[RegClass]) -> uint {
|
||||
let mut len = 1u;
|
||||
for cls.each |c| {
|
||||
if *c != sseup_class {
|
||||
if *c != SSEUp {
|
||||
break;
|
||||
}
|
||||
len += 1u;
|
||||
@ -310,20 +316,20 @@ fn llreg_ty(cls: &[RegClass]) -> Type {
|
||||
let e = cls.len();
|
||||
while i < e {
|
||||
match cls[i] {
|
||||
integer_class => {
|
||||
Int => {
|
||||
tys.push(Type::i64());
|
||||
}
|
||||
sse_fv_class => {
|
||||
SSEFv => {
|
||||
let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u;
|
||||
let vec_ty = Type::vector(Type::f32(), vec_len);
|
||||
let vec_ty = Type::vector(&Type::f32(), vec_len as u64);
|
||||
tys.push(vec_ty);
|
||||
i += vec_len;
|
||||
loop;
|
||||
}
|
||||
sse_fs_class => {
|
||||
SSEFs => {
|
||||
tys.push(Type::f32());
|
||||
}
|
||||
sse_ds_class => {
|
||||
SSEDs => {
|
||||
tys.push(Type::f64());
|
||||
}
|
||||
_ => fail!("llregtype: unhandled class")
|
||||
@ -341,6 +347,7 @@ fn x86_64_tys(atys: &[Type],
|
||||
fn x86_64_ty(ty: Type,
|
||||
is_mem_cls: &fn(cls: &[RegClass]) -> bool,
|
||||
attr: Attribute) -> (LLVMType, Option<Attribute>) {
|
||||
|
||||
let (cast, attr, ty) = if !ty.is_reg_ty() {
|
||||
let cls = classify_ty(ty);
|
||||
if is_mem_cls(cls) {
|
||||
@ -348,8 +355,11 @@ fn x86_64_tys(atys: &[Type],
|
||||
} else {
|
||||
(true, option::None, llreg_ty(cls))
|
||||
}
|
||||
} else {
|
||||
(false, option::None, ty)
|
||||
};
|
||||
return (LLVMType { cast: cast, ty: ty }, attr);
|
||||
|
||||
(LLVMType { cast: cast, ty: ty }, attr)
|
||||
}
|
||||
|
||||
let mut arg_tys = ~[];
|
||||
|
@ -45,6 +45,8 @@ use middle::typeck;
|
||||
use middle::typeck::coherence::make_substs_for_receiver_types;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::vec;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
@ -526,7 +528,7 @@ pub fn trans_call_inner(in_cx: block,
|
||||
let (llfn, llenv) = unsafe {
|
||||
match callee.data {
|
||||
Fn(d) => {
|
||||
(d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to()))
|
||||
(d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to().to_ref()))
|
||||
}
|
||||
Method(d) => {
|
||||
// Weird but true: we pass self in the *environment* slot!
|
||||
@ -653,7 +655,7 @@ pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: expr::Dest)
|
||||
expr::Ignore => {
|
||||
if ty::type_is_nil(retty) {
|
||||
unsafe {
|
||||
llvm::LLVMGetUndef(Type::nil().ptr_to())
|
||||
llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref())
|
||||
}
|
||||
} else {
|
||||
alloc_ty(bcx, retty)
|
||||
@ -777,7 +779,7 @@ pub fn trans_arg_expr(bcx: block,
|
||||
// to have type lldestty (the callee's expected type).
|
||||
let llformal_arg_ty = type_of::type_of(ccx, formal_arg_ty);
|
||||
unsafe {
|
||||
val = llvm::LLVMGetUndef(llformal_arg_ty);
|
||||
val = llvm::LLVMGetUndef(llformal_arg_ty.to_ref());
|
||||
}
|
||||
} else {
|
||||
// FIXME(#3548) use the adjustments table
|
||||
|
@ -26,6 +26,8 @@ use middle::trans::type_of::*;
|
||||
use middle::ty;
|
||||
use util::ppaux::ty_to_str;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use syntax::ast;
|
||||
|
@ -31,6 +31,8 @@ use middle::typeck;
|
||||
use middle::borrowck::root_map_key;
|
||||
use util::ppaux::{Repr};
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::cast::transmute;
|
||||
use core::cast;
|
||||
use core::hashmap::{HashMap};
|
||||
@ -58,29 +60,11 @@ pub fn new_namegen() -> namegen {
|
||||
f
|
||||
}
|
||||
|
||||
pub type addrspace = c_uint;
|
||||
|
||||
// Address spaces communicate to LLVM which destructors need to run for
|
||||
// specific types.
|
||||
// 0 is ignored by the GC, and is used for all non-GC'd pointers.
|
||||
// 1 is for opaque GC'd boxes.
|
||||
// >= 2 are for specific types (e.g. resources).
|
||||
pub static default_addrspace: addrspace = 0;
|
||||
pub static gc_box_addrspace: addrspace = 1;
|
||||
|
||||
pub type addrspace_gen = @fn() -> addrspace;
|
||||
pub fn new_addrspace_gen() -> addrspace_gen {
|
||||
let i = @mut 1;
|
||||
let result: addrspace_gen = || { *i += 1; *i };
|
||||
result
|
||||
}
|
||||
|
||||
pub struct tydesc_info {
|
||||
ty: ty::t,
|
||||
tydesc: ValueRef,
|
||||
size: ValueRef,
|
||||
align: ValueRef,
|
||||
addrspace: addrspace,
|
||||
take_glue: Option<ValueRef>,
|
||||
drop_glue: Option<ValueRef>,
|
||||
free_glue: Option<ValueRef>,
|
||||
@ -345,39 +329,14 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype {
|
||||
}
|
||||
}
|
||||
|
||||
// This is not the same as datum::Datum::root(), which is used to keep copies
|
||||
// of @ values live for as long as a borrowed pointer to the interior exists.
|
||||
// In the new GC, we can identify immediates on the stack without difficulty,
|
||||
// but have trouble knowing where non-immediates are on the stack. For
|
||||
// non-immediates, we must add an additional level of indirection, which
|
||||
// allows us to alloca a pointer with the right addrspace.
|
||||
pub fn root_for_cleanup(bcx: block, v: ValueRef, t: ty::t)
|
||||
-> (ValueRef, bool) {
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
let addrspace = base::get_tydesc(ccx, t).addrspace;
|
||||
if addrspace > gc_box_addrspace {
|
||||
let llty = type_of::type_of_rooted(ccx, t);
|
||||
let root = base::alloca(bcx, llty);
|
||||
build::Store(bcx, build::PointerCast(bcx, v, llty), root);
|
||||
(root, true)
|
||||
} else {
|
||||
(v, false)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) {
|
||||
if !ty::type_needs_drop(bcx.tcx(), t) { return; }
|
||||
debug!("add_clean(%s, %s, %s)",
|
||||
bcx.to_str(),
|
||||
bcx.val_to_str(val),
|
||||
t.repr(bcx.tcx()));
|
||||
let (root, rooted) = root_for_cleanup(bcx, val, t);
|
||||
|
||||
debug!("add_clean(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx()));
|
||||
|
||||
let cleanup_type = cleanup_type(bcx.tcx(), t);
|
||||
do in_scope_cx(bcx) |scope_info| {
|
||||
scope_info.cleanups.push(
|
||||
clean(|a| glue::drop_ty_root(a, root, rooted, t),
|
||||
cleanup_type));
|
||||
scope_info.cleanups.push(clean(|a| glue::drop_ty(a, val, t), cleanup_type));
|
||||
grow_scope_clean(scope_info);
|
||||
}
|
||||
}
|
||||
@ -400,12 +359,9 @@ pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) {
|
||||
debug!("add_clean_temp_mem(%s, %s, %s)",
|
||||
bcx.to_str(), bcx.val_to_str(val),
|
||||
t.repr(bcx.tcx()));
|
||||
let (root, rooted) = root_for_cleanup(bcx, val, t);
|
||||
let cleanup_type = cleanup_type(bcx.tcx(), t);
|
||||
do in_scope_cx(bcx) |scope_info| {
|
||||
scope_info.cleanups.push(
|
||||
clean_temp(val, |a| glue::drop_ty_root(a, root, rooted, t),
|
||||
cleanup_type));
|
||||
scope_info.cleanups.push(clean_temp(val, |a| glue::drop_ty(a, val, t), cleanup_type));
|
||||
grow_scope_clean(scope_info);
|
||||
}
|
||||
}
|
||||
@ -431,12 +387,8 @@ pub fn add_clean_return_to_mut(bcx: block,
|
||||
scope_info.cleanups.push(
|
||||
clean_temp(
|
||||
frozen_val_ref,
|
||||
|bcx| write_guard::return_to_mut(bcx,
|
||||
root_key,
|
||||
frozen_val_ref,
|
||||
bits_val_ref,
|
||||
filename_val,
|
||||
line_val),
|
||||
|bcx| write_guard::return_to_mut(bcx, root_key, frozen_val_ref, bits_val_ref,
|
||||
filename_val, line_val),
|
||||
normal_exit_only));
|
||||
grow_scope_clean(scope_info);
|
||||
}
|
||||
@ -621,9 +573,9 @@ impl Result {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn val_ty(v: ValueRef) -> TypeRef {
|
||||
pub fn val_ty(v: ValueRef) -> Type {
|
||||
unsafe {
|
||||
return llvm::LLVMTypeOf(v);
|
||||
Type::from_ref(llvm::LLVMTypeOf(v))
|
||||
}
|
||||
}
|
||||
|
||||
@ -706,313 +658,6 @@ impl block_ {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// LLVM type constructors.
|
||||
pub fn T_void() -> TypeRef {
|
||||
unsafe { return llvm::LLVMVoidTypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_nil() -> TypeRef {
|
||||
return T_struct([], false)
|
||||
}
|
||||
|
||||
pub fn T_metadata() -> TypeRef {
|
||||
unsafe { return llvm::LLVMMetadataTypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_i1() -> TypeRef {
|
||||
unsafe { return llvm::LLVMInt1TypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_i8() -> TypeRef {
|
||||
unsafe { return llvm::LLVMInt8TypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_i16() -> TypeRef {
|
||||
unsafe { return llvm::LLVMInt16TypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_i32() -> TypeRef {
|
||||
unsafe { return llvm::LLVMInt32TypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_i64() -> TypeRef {
|
||||
unsafe { return llvm::LLVMInt64TypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_f32() -> TypeRef {
|
||||
unsafe { return llvm::LLVMFloatTypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_f64() -> TypeRef {
|
||||
unsafe { return llvm::LLVMDoubleTypeInContext(base::task_llcx()); }
|
||||
}
|
||||
|
||||
pub fn T_bool() -> TypeRef { return T_i8(); }
|
||||
|
||||
pub fn T_int(targ_cfg: &session::config) -> TypeRef {
|
||||
return match targ_cfg.arch {
|
||||
X86 => T_i32(),
|
||||
X86_64 => T_i64(),
|
||||
Arm => T_i32(),
|
||||
Mips => T_i32()
|
||||
};
|
||||
}
|
||||
|
||||
pub fn T_int_ty(cx: &CrateContext, t: ast::int_ty) -> TypeRef {
|
||||
match t {
|
||||
ast::ty_i => cx.int_type,
|
||||
ast::ty_char => T_char(),
|
||||
ast::ty_i8 => T_i8(),
|
||||
ast::ty_i16 => T_i16(),
|
||||
ast::ty_i32 => T_i32(),
|
||||
ast::ty_i64 => T_i64()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_uint_ty(cx: &CrateContext, t: ast::uint_ty) -> TypeRef {
|
||||
match t {
|
||||
ast::ty_u => cx.int_type,
|
||||
ast::ty_u8 => T_i8(),
|
||||
ast::ty_u16 => T_i16(),
|
||||
ast::ty_u32 => T_i32(),
|
||||
ast::ty_u64 => T_i64()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_float_ty(cx: &CrateContext, t: ast::float_ty) -> TypeRef {
|
||||
match t {
|
||||
ast::ty_f => cx.float_type,
|
||||
ast::ty_f32 => T_f32(),
|
||||
ast::ty_f64 => T_f64()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_float(targ_cfg: &session::config) -> TypeRef {
|
||||
return match targ_cfg.arch {
|
||||
X86 => T_f64(),
|
||||
X86_64 => T_f64(),
|
||||
Arm => T_f64(),
|
||||
Mips => T_f64()
|
||||
};
|
||||
}
|
||||
|
||||
pub fn T_char() -> TypeRef { return T_i32(); }
|
||||
|
||||
pub fn T_size_t(targ_cfg: &session::config) -> TypeRef {
|
||||
return T_int(targ_cfg);
|
||||
}
|
||||
|
||||
pub fn T_fn(inputs: &[TypeRef], output: TypeRef) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMFunctionType(output, to_ptr(inputs),
|
||||
inputs.len() as c_uint,
|
||||
False);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_fn_pair(cx: &CrateContext, tfn: TypeRef) -> TypeRef {
|
||||
return T_struct([T_ptr(tfn), T_opaque_cbox_ptr(cx)], false);
|
||||
}
|
||||
|
||||
pub fn T_ptr(t: TypeRef) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMPointerType(t, default_addrspace);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMPointerType(t, addrspace);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_struct(elts: &[TypeRef], packed: bool) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMStructTypeInContext(base::task_llcx(),
|
||||
to_ptr(elts),
|
||||
elts.len() as c_uint,
|
||||
packed as Bool);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_named_struct(name: &str) -> TypeRef {
|
||||
unsafe {
|
||||
return str::as_c_str(name, |buf| {
|
||||
llvm::LLVMStructCreateNamed(base::task_llcx(), buf)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_struct_body(t: TypeRef, elts: &[TypeRef], packed: bool) {
|
||||
unsafe {
|
||||
llvm::LLVMStructSetBody(t,
|
||||
to_ptr(elts),
|
||||
elts.len() as c_uint,
|
||||
packed as Bool);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_empty_struct() -> TypeRef { return T_struct([], false); }
|
||||
|
||||
// A vtable is, in reality, a vtable pointer followed by zero or more pointers
|
||||
// to tydescs and other vtables that it closes over. But the types and number
|
||||
// of those are rarely known to the code that needs to manipulate them, so
|
||||
// they are described by this opaque type.
|
||||
pub fn T_vtable() -> TypeRef { T_array(T_ptr(T_i8()), 1u) }
|
||||
|
||||
pub fn T_tydesc_field(cx: &CrateContext, field: uint) -> TypeRef {
|
||||
// Bit of a kludge: pick the fn typeref out of the tydesc..
|
||||
|
||||
unsafe {
|
||||
let mut tydesc_elts: ~[TypeRef] =
|
||||
vec::from_elem::<TypeRef>(abi::n_tydesc_fields,
|
||||
T_nil());
|
||||
llvm::LLVMGetStructElementTypes(cx.tydesc_type, &mut tydesc_elts[0]);
|
||||
let t = llvm::LLVMGetElementType(tydesc_elts[field]);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_generic_glue_fn(cx: &mut CrateContext) -> TypeRef {
|
||||
let s = @"glue_fn";
|
||||
match cx.tn.find_type(s) {
|
||||
Some(t) => return t,
|
||||
_ => ()
|
||||
}
|
||||
let t = T_tydesc_field(cx, abi::tydesc_field_drop_glue);
|
||||
cx.tn.associate_type(s, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
pub fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
|
||||
let tydesc = T_named_struct("tydesc");
|
||||
let tydescpp = T_ptr(T_ptr(tydesc));
|
||||
let pvoid = T_ptr(T_i8());
|
||||
let glue_fn_ty =
|
||||
T_ptr(T_fn([T_ptr(T_nil()), tydescpp, pvoid], T_void()));
|
||||
|
||||
let int_type = T_int(targ_cfg);
|
||||
let elems =
|
||||
~[int_type, int_type,
|
||||
glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty,
|
||||
T_ptr(T_i8()), T_ptr(T_i8())];
|
||||
set_struct_body(tydesc, elems, false);
|
||||
return tydesc;
|
||||
}
|
||||
|
||||
pub fn T_array(t: TypeRef, n: uint) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMArrayType(t, n as c_uint);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_vector(t: TypeRef, n: uint) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMVectorType(t, n as c_uint);
|
||||
}
|
||||
}
|
||||
|
||||
// Interior vector.
|
||||
pub fn T_vec2(targ_cfg: &session::config, t: TypeRef) -> TypeRef {
|
||||
return T_struct([T_int(targ_cfg), // fill
|
||||
T_int(targ_cfg), // alloc
|
||||
T_array(t, 0u)], // elements
|
||||
false);
|
||||
}
|
||||
|
||||
pub fn T_vec(ccx: &CrateContext, t: TypeRef) -> TypeRef {
|
||||
return T_vec2(ccx.sess.targ_cfg, t);
|
||||
}
|
||||
|
||||
// Note that the size of this one is in bytes.
|
||||
pub fn T_opaque_vec(targ_cfg: @session::config) -> TypeRef {
|
||||
return T_vec2(targ_cfg, T_i8());
|
||||
}
|
||||
|
||||
pub fn T_box_header_fields(cx: &CrateContext) -> ~[TypeRef] {
|
||||
let ptr = T_ptr(T_i8());
|
||||
return ~[cx.int_type, T_ptr(cx.tydesc_type), ptr, ptr];
|
||||
}
|
||||
|
||||
pub fn T_box_header(cx: &CrateContext) -> TypeRef {
|
||||
return T_struct(T_box_header_fields(cx), false);
|
||||
}
|
||||
|
||||
pub fn T_box(cx: &CrateContext, t: TypeRef) -> TypeRef {
|
||||
return T_struct(vec::append(T_box_header_fields(cx), [t]), false);
|
||||
}
|
||||
|
||||
pub fn T_box_ptr(t: TypeRef) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMPointerType(t, gc_box_addrspace);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_opaque_box(cx: &CrateContext) -> TypeRef {
|
||||
return T_box(cx, T_i8());
|
||||
}
|
||||
|
||||
pub fn T_opaque_box_ptr(cx: &CrateContext) -> TypeRef {
|
||||
return T_box_ptr(T_opaque_box(cx));
|
||||
}
|
||||
|
||||
pub fn T_unique(cx: &CrateContext, t: TypeRef) -> TypeRef {
|
||||
return T_struct(vec::append(T_box_header_fields(cx), [t]), false);
|
||||
}
|
||||
|
||||
pub fn T_unique_ptr(t: TypeRef) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMPointerType(t, gc_box_addrspace);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_port(cx: &CrateContext, _t: TypeRef) -> TypeRef {
|
||||
return T_struct([cx.int_type], false); // Refcount
|
||||
|
||||
}
|
||||
|
||||
pub fn T_chan(cx: &CrateContext, _t: TypeRef) -> TypeRef {
|
||||
return T_struct([cx.int_type], false); // Refcount
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn T_opaque_cbox_ptr(cx: &CrateContext) -> TypeRef {
|
||||
// closures look like boxes (even when they are ~fn or &fn)
|
||||
// see trans_closure.rs
|
||||
return T_opaque_box_ptr(cx);
|
||||
}
|
||||
|
||||
pub fn T_enum_discrim(cx: &CrateContext) -> TypeRef {
|
||||
return cx.int_type;
|
||||
}
|
||||
|
||||
pub fn T_captured_tydescs(cx: &CrateContext, n: uint) -> TypeRef {
|
||||
return T_struct(vec::from_elem::<TypeRef>(n, T_ptr(cx.tydesc_type)), false);
|
||||
}
|
||||
|
||||
pub fn T_opaque_trait(cx: &CrateContext, store: ty::TraitStore) -> TypeRef {
|
||||
match store {
|
||||
ty::BoxTraitStore => {
|
||||
T_struct([T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)], false)
|
||||
}
|
||||
ty::UniqTraitStore => {
|
||||
T_struct([T_ptr(cx.tydesc_type),
|
||||
T_unique_ptr(T_unique(cx, T_i8()))],
|
||||
false)
|
||||
}
|
||||
ty::RegionTraitStore(_) => {
|
||||
T_struct([T_ptr(cx.tydesc_type), T_ptr(T_i8())], false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn T_opaque_port_ptr() -> TypeRef { return T_ptr(T_i8()); }
|
||||
|
||||
pub fn T_opaque_chan_ptr() -> TypeRef { return T_ptr(T_i8()); }
|
||||
*/
|
||||
|
||||
// Let T be the content of a box @T. tuplify_box_ty(t) returns the
|
||||
// representation of @T as a tuple (i.e., the ty::t version of what T_box()
|
||||
// returns).
|
||||
@ -1101,7 +746,7 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef {
|
||||
};
|
||||
|
||||
let gsym = token::gensym("str");
|
||||
let g = fmt!("str%u", gsym).as_c_str |buf| {
|
||||
let g = do fmt!("str%u", gsym).as_c_str |buf| {
|
||||
llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf)
|
||||
};
|
||||
llvm::LLVMSetInitializer(g, sc);
|
||||
@ -1138,7 +783,8 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef {
|
||||
let mut i = 0u;
|
||||
let mut elts: ~[ValueRef] = ~[];
|
||||
while i < size { elts.push(C_u8(0u)); i += 1u; }
|
||||
return llvm::LLVMConstArray(Type::i8(), vec::raw::to_ptr(elts), elts.len() as c_uint);
|
||||
return llvm::LLVMConstArray(Type::i8().to_ref(),
|
||||
vec::raw::to_ptr(elts), elts.len() as c_uint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1158,17 +804,17 @@ pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn C_named_struct(T: TypeRef, elts: &[ValueRef]) -> ValueRef {
|
||||
pub fn C_named_struct(T: Type, elts: &[ValueRef]) -> ValueRef {
|
||||
unsafe {
|
||||
do vec::as_imm_buf(elts) |ptr, len| {
|
||||
llvm::LLVMConstNamedStruct(T, ptr, len as c_uint)
|
||||
llvm::LLVMConstNamedStruct(T.to_ref(), ptr, len as c_uint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn C_array(ty: TypeRef, elts: &[ValueRef]) -> ValueRef {
|
||||
pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
|
||||
unsafe {
|
||||
return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts), elts.len() as c_uint);
|
||||
return llvm::LLVMConstArray(ty.to_ref(), vec::raw::to_ptr(elts), elts.len() as c_uint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1193,7 +839,7 @@ pub fn C_shape(ccx: &CrateContext, bytes: ~[u8]) -> ValueRef {
|
||||
let llglobal = do name.as_c_str |buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape).to_ref(), buf)
|
||||
};
|
||||
llvm::LLVMSetInitializer(llglobal, llshape.to_ref());
|
||||
llvm::LLVMSetInitializer(llglobal, llshape);
|
||||
llvm::LLVMSetGlobalConstant(llglobal, True);
|
||||
lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
|
||||
return llvm::LLVMConstPointerCast(llglobal, Type::i8p().to_ref());
|
||||
|
@ -11,7 +11,7 @@
|
||||
use core::prelude::*;
|
||||
|
||||
use back::abi;
|
||||
use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, TypeRef, Bool,
|
||||
use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool,
|
||||
True, False};
|
||||
use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
|
||||
RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE};
|
||||
@ -30,6 +30,8 @@ use middle::trans::type_of;
|
||||
use middle::ty;
|
||||
use util::ppaux::{Repr, ty_to_str};
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::libc::c_uint;
|
||||
use core::str;
|
||||
use syntax::{ast, ast_util, ast_map};
|
||||
@ -38,28 +40,28 @@ pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit)
|
||||
-> ValueRef {
|
||||
let _icx = cx.insn_ctxt("trans_lit");
|
||||
match lit.node {
|
||||
ast::lit_int(i, t) => C_integral(T_int_ty(cx, t), i as u64, True),
|
||||
ast::lit_uint(u, t) => C_integral(T_uint_ty(cx, t), u, False),
|
||||
ast::lit_int(i, t) => C_integral(Type::int_from_ty(cx, t), i as u64, true),
|
||||
ast::lit_uint(u, t) => C_integral(Type::uint_from_ty(cx, t), u, false),
|
||||
ast::lit_int_unsuffixed(i) => {
|
||||
let lit_int_ty = ty::node_id_to_type(cx.tcx, e.id);
|
||||
match ty::get(lit_int_ty).sty {
|
||||
ty::ty_int(t) => {
|
||||
C_integral(T_int_ty(cx, t), i as u64, True)
|
||||
C_integral(Type::int_from_ty(cx, t), i as u64, true)
|
||||
}
|
||||
ty::ty_uint(t) => {
|
||||
C_integral(T_uint_ty(cx, t), i as u64, False)
|
||||
C_integral(Type::uint_from_ty(cx, t), i as u64, false)
|
||||
}
|
||||
_ => cx.sess.span_bug(lit.span,
|
||||
fmt!("integer literal has type %s (expected int or uint)",
|
||||
ty_to_str(cx.tcx, lit_int_ty)))
|
||||
}
|
||||
}
|
||||
ast::lit_float(fs, t) => C_floating(fs, T_float_ty(cx, t)),
|
||||
ast::lit_float(fs, t) => C_floating(fs, Type::float_from_ty(cx, t)),
|
||||
ast::lit_float_unsuffixed(fs) => {
|
||||
let lit_float_ty = ty::node_id_to_type(cx.tcx, e.id);
|
||||
match ty::get(lit_float_ty).sty {
|
||||
ty::ty_float(t) => {
|
||||
C_floating(fs, T_float_ty(cx, t))
|
||||
C_floating(fs, Type::float_from_ty(cx, t))
|
||||
}
|
||||
_ => {
|
||||
cx.sess.span_bug(lit.span,
|
||||
@ -73,16 +75,16 @@ pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: TypeRef) -> ValueRef {
|
||||
pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: Type) -> ValueRef {
|
||||
unsafe {
|
||||
let b = llvm::LLVMConstPointerCast(a, T_ptr(t));
|
||||
let b = llvm::LLVMConstPointerCast(a, t.ptr_to().to_ref());
|
||||
assert!(cx.const_globals.insert(b as int, a));
|
||||
b
|
||||
}
|
||||
}
|
||||
|
||||
pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr])
|
||||
-> (ValueRef, ValueRef, TypeRef) {
|
||||
-> (ValueRef, ValueRef, Type) {
|
||||
unsafe {
|
||||
let vec_ty = ty::expr_ty(cx.tcx, e);
|
||||
let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
|
||||
@ -102,8 +104,8 @@ pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr])
|
||||
|
||||
fn const_addr_of(cx: @mut CrateContext, cv: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
let gv = do str::as_c_str("const") |name| {
|
||||
llvm::LLVMAddGlobal(cx.llmod, val_ty(cv), name)
|
||||
let gv = do "const".as_c_str |name| {
|
||||
llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
|
||||
};
|
||||
llvm::LLVMSetInitializer(gv, cv);
|
||||
llvm::LLVMSetGlobalConstant(gv, True);
|
||||
@ -180,7 +182,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
|
||||
match adjustment {
|
||||
None => { }
|
||||
Some(@ty::AutoAddEnv(ty::re_static, ast::BorrowedSigil)) => {
|
||||
llconst = C_struct([llconst, C_null(T_opaque_box_ptr(cx))])
|
||||
llconst = C_struct([llconst, C_null(Type::opaque_box(cx).ptr_to())])
|
||||
}
|
||||
Some(@ty::AutoAddEnv(ref r, ref s)) => {
|
||||
cx.sess.span_bug(e.span, fmt!("unexpected static function: \
|
||||
@ -349,9 +351,9 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
|
||||
ty::ty_bool => {
|
||||
// Somewhat questionable, but I believe this is
|
||||
// correct.
|
||||
let te = llvm::LLVMConstTrunc(te, T_i1());
|
||||
let te = llvm::LLVMConstTrunc(te, Type::i1().to_ref());
|
||||
let te = llvm::LLVMConstNot(te);
|
||||
llvm::LLVMConstZExt(te, T_bool())
|
||||
llvm::LLVMConstZExt(te, Type::bool().to_ref())
|
||||
}
|
||||
_ => llvm::LLVMConstNot(te),
|
||||
}
|
||||
@ -426,21 +428,21 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
|
||||
|
||||
(expr::cast_integral, expr::cast_integral) => {
|
||||
let s = ty::type_is_signed(basety) as Bool;
|
||||
llvm::LLVMConstIntCast(v, llty, s)
|
||||
llvm::LLVMConstIntCast(v, llty.to_ref(), s)
|
||||
}
|
||||
(expr::cast_integral, expr::cast_float) => {
|
||||
if ty::type_is_signed(basety) {
|
||||
llvm::LLVMConstSIToFP(v, llty)
|
||||
llvm::LLVMConstSIToFP(v, llty.to_ref())
|
||||
} else {
|
||||
llvm::LLVMConstUIToFP(v, llty)
|
||||
llvm::LLVMConstUIToFP(v, llty.to_ref())
|
||||
}
|
||||
}
|
||||
(expr::cast_float, expr::cast_float) => {
|
||||
llvm::LLVMConstFPCast(v, llty)
|
||||
llvm::LLVMConstFPCast(v, llty.to_ref())
|
||||
}
|
||||
(expr::cast_float, expr::cast_integral) => {
|
||||
if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) }
|
||||
else { llvm::LLVMConstFPToUI(v, llty) }
|
||||
if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty.to_ref()) }
|
||||
else { llvm::LLVMConstFPToUI(v, llty.to_ref()) }
|
||||
}
|
||||
(expr::cast_enum, expr::cast_integral) |
|
||||
(expr::cast_enum, expr::cast_float) => {
|
||||
@ -451,18 +453,18 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
|
||||
match ety_cast {
|
||||
expr::cast_integral => {
|
||||
let s = ty::type_is_signed(ety) as Bool;
|
||||
llvm::LLVMConstIntCast(iv, llty, s)
|
||||
llvm::LLVMConstIntCast(iv, llty.to_ref(), s)
|
||||
}
|
||||
expr::cast_float => llvm::LLVMConstUIToFP(iv, llty),
|
||||
expr::cast_float => llvm::LLVMConstUIToFP(iv, llty.to_ref()),
|
||||
_ => cx.sess.bug("enum cast destination is not \
|
||||
integral or float")
|
||||
}
|
||||
}
|
||||
(expr::cast_pointer, expr::cast_pointer) => {
|
||||
llvm::LLVMConstPointerCast(v, llty)
|
||||
llvm::LLVMConstPointerCast(v, llty.to_ref())
|
||||
}
|
||||
(expr::cast_integral, expr::cast_pointer) => {
|
||||
llvm::LLVMConstIntToPtr(v, llty)
|
||||
llvm::LLVMConstIntToPtr(v, llty.to_ref())
|
||||
}
|
||||
_ => {
|
||||
cx.sess.impossible_case(e.span,
|
||||
@ -513,7 +515,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
|
||||
let (cv, sz, llunitty) = const_vec(cx, e, *es);
|
||||
let llty = val_ty(cv);
|
||||
let gv = do str::as_c_str("const") |name| {
|
||||
llvm::LLVMAddGlobal(cx.llmod, llty, name)
|
||||
llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
|
||||
};
|
||||
llvm::LLVMSetInitializer(gv, cv);
|
||||
llvm::LLVMSetGlobalConstant(gv, True);
|
||||
|
@ -12,7 +12,7 @@ use core::prelude::*;
|
||||
|
||||
use back::{upcall};
|
||||
use driver::session;
|
||||
use lib::llvm::{ContextRef, ModuleRef, ValueRef, TypeRef};
|
||||
use lib::llvm::{ContextRef, ModuleRef, ValueRef};
|
||||
use lib::llvm::{llvm, TargetData, TypeNames};
|
||||
use lib::llvm::{mk_target_data};
|
||||
use lib;
|
||||
@ -36,8 +36,8 @@ use core::local_data;
|
||||
use extra::time;
|
||||
use syntax::ast;
|
||||
|
||||
use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen,addrspace_gen};
|
||||
use middle::trans::common::{mono_id,new_namegen,new_addrspace_gen};
|
||||
use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen};
|
||||
use middle::trans::common::{mono_id,new_namegen};
|
||||
|
||||
use middle::trans::base::{decl_crate_map};
|
||||
|
||||
@ -94,11 +94,10 @@ pub struct CrateContext {
|
||||
impl_method_cache: HashMap<(ast::def_id, ast::ident), ast::def_id>,
|
||||
|
||||
module_data: HashMap<~str, ValueRef>,
|
||||
lltypes: HashMap<ty::t, TypeRef>,
|
||||
llsizingtypes: HashMap<ty::t, TypeRef>,
|
||||
lltypes: HashMap<ty::t, Type>,
|
||||
llsizingtypes: HashMap<ty::t, Type>,
|
||||
adt_reprs: HashMap<ty::t, @adt::Repr>,
|
||||
names: namegen,
|
||||
next_addrspace: addrspace_gen,
|
||||
symbol_hasher: hash::State,
|
||||
type_hashcodes: HashMap<ty::t, @str>,
|
||||
type_short_names: HashMap<ty::t, ~str>,
|
||||
@ -151,8 +150,8 @@ impl CrateContext {
|
||||
let tydesc_type = Type::tydesc(targ_cfg.arch);
|
||||
let opaque_vec_type = Type::opaque_vec(targ_cfg.arch);
|
||||
|
||||
let str_slice_ty = Type::named_struct("str_slice");
|
||||
str_slice_ty.set_struct_body([Type::i8p(), int_type]);
|
||||
let mut str_slice_ty = Type::named_struct("str_slice");
|
||||
str_slice_ty.set_struct_body([Type::i8p(), int_type], false);
|
||||
|
||||
tn.associate_type("tydesc", &tydesc_type);
|
||||
tn.associate_type("str_slice", &str_slice_ty);
|
||||
@ -197,7 +196,6 @@ impl CrateContext {
|
||||
llsizingtypes: HashMap::new(),
|
||||
adt_reprs: HashMap::new(),
|
||||
names: new_namegen(),
|
||||
next_addrspace: new_addrspace_gen(),
|
||||
symbol_hasher: symbol_hasher,
|
||||
type_hashcodes: HashMap::new(),
|
||||
type_short_names: HashMap::new(),
|
||||
|
@ -24,6 +24,8 @@ use middle::ty;
|
||||
use util::common::indenter;
|
||||
use util::ppaux;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use syntax::ast;
|
||||
@ -204,7 +206,7 @@ pub fn trans_log(log_ex: @ast::expr,
|
||||
let global;
|
||||
unsafe {
|
||||
global = str::as_c_str(s, |buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, Type::i32(), buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
|
||||
});
|
||||
llvm::LLVMSetGlobalConstant(global, False);
|
||||
llvm::LLVMSetInitializer(global, C_null(Type::i32()));
|
||||
|
@ -152,6 +152,8 @@ use middle::ty;
|
||||
use util::common::indenter;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::cast::transmute;
|
||||
use core::hashmap::HashMap;
|
||||
use core::vec;
|
||||
@ -981,9 +983,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||
let symbol = csearch::get_symbol(
|
||||
bcx.ccx().sess.cstore,
|
||||
did);
|
||||
let llval = llvm::LLVMAddGlobal(
|
||||
bcx.ccx().llmod,
|
||||
llty,
|
||||
let llval = llvm::LLVMAddGlobal( bcx.ccx().llmod, llty.to_ref(),
|
||||
transmute::<&u8,*i8>(&symbol[0]));
|
||||
let extern_const_values = &mut bcx.ccx().extern_const_values;
|
||||
extern_const_values.insert(did, llval);
|
||||
@ -1552,8 +1552,8 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type,
|
||||
llsrc: ValueRef, signed: bool) -> ValueRef {
|
||||
let _icx = bcx.insn_ctxt("int_cast");
|
||||
unsafe {
|
||||
let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype);
|
||||
let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype);
|
||||
let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref());
|
||||
let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype.to_ref());
|
||||
return if dstsz == srcsz {
|
||||
BitCast(bcx, llsrc, lldsttype)
|
||||
} else if srcsz > dstsz {
|
||||
@ -1569,8 +1569,8 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type,
|
||||
fn float_cast(bcx: block, lldsttype: Type, llsrctype: Type,
|
||||
llsrc: ValueRef) -> ValueRef {
|
||||
let _icx = bcx.insn_ctxt("float_cast");
|
||||
let srcsz = lib::llvm::float_width(llsrctype);
|
||||
let dstsz = lib::llvm::float_width(lldsttype);
|
||||
let srcsz = llsrctype.float_width();
|
||||
let dstsz = lldsttype.float_width();
|
||||
return if dstsz > srcsz {
|
||||
FPExt(bcx, llsrc, lldsttype)
|
||||
} else if srcsz > dstsz {
|
||||
|
@ -44,6 +44,7 @@ use syntax::parse::token;
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips};
|
||||
use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall,
|
||||
Cdecl, Aapcs, C};
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
fn abi_info(ccx: @mut CrateContext) -> @cabi::ABIInfo {
|
||||
return match ccx.sess.targ_cfg.arch {
|
||||
@ -122,7 +123,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes {
|
||||
llsig: llsig,
|
||||
ret_def: ret_def,
|
||||
bundle_ty: bundle_ty,
|
||||
shim_fn_ty: Type::func([bundle_ty.ptr_to()], Type::void()),
|
||||
shim_fn_ty: Type::func([bundle_ty.ptr_to()], &Type::void()),
|
||||
fn_ty: fn_ty
|
||||
}
|
||||
}
|
||||
@ -220,12 +221,9 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
|
||||
let return_context = raw_block(fcx, false, fcx.llreturn);
|
||||
|
||||
let llfunctiontype = val_ty(llwrapfn);
|
||||
let llfunctiontype =
|
||||
::lib::llvm::llvm::LLVMGetElementType(llfunctiontype);
|
||||
let llfunctionreturntype =
|
||||
::lib::llvm::llvm::LLVMGetReturnType(llfunctiontype);
|
||||
if ::lib::llvm::llvm::LLVMGetTypeKind(llfunctionreturntype) ==
|
||||
::lib::llvm::Void {
|
||||
let llfunctiontype = llfunctiontype.element_type();
|
||||
let return_type = llfunctiontype.return_type();
|
||||
if return_type.kind() == ::lib::llvm::Void {
|
||||
// XXX: This might be wrong if there are any functions for which
|
||||
// the C ABI specifies a void output pointer and the Rust ABI
|
||||
// does not.
|
||||
@ -233,9 +231,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
|
||||
} else {
|
||||
// Cast if we have to...
|
||||
// XXX: This is ugly.
|
||||
let llretptr = BitCast(return_context,
|
||||
fcx.llretptr.get(),
|
||||
llfunctionreturntype.ptr_to());
|
||||
let llretptr = BitCast(return_context, fcx.llretptr.get(), return_type.ptr_to());
|
||||
Ret(return_context, Load(return_context, llretptr));
|
||||
}
|
||||
}
|
||||
@ -636,6 +632,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
|
||||
}
|
||||
}
|
||||
|
||||
build_return(bcx);
|
||||
finish_fn(fcx, lltop);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ use back::abi;
|
||||
use back::link::*;
|
||||
use driver::session;
|
||||
use lib;
|
||||
use lib::llvm::{llvm, ValueRef, Type, True};
|
||||
use lib::llvm::{llvm, ValueRef, True};
|
||||
use middle::trans::adt;
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::callee;
|
||||
@ -29,12 +29,14 @@ use middle::trans::expr;
|
||||
use middle::trans::machine::*;
|
||||
use middle::trans::reflect;
|
||||
use middle::trans::tvec;
|
||||
use middle::trans::type_of::{type_of, type_of_glue_fn};
|
||||
use middle::trans::type_of::type_of;
|
||||
use middle::trans::uniq;
|
||||
use middle::ty;
|
||||
use util::ppaux;
|
||||
use util::ppaux::ty_to_short_str;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::io;
|
||||
use core::libc::c_uint;
|
||||
use core::str;
|
||||
@ -76,16 +78,6 @@ pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block {
|
||||
return cx;
|
||||
}
|
||||
|
||||
pub fn drop_ty_root(bcx: block, v: ValueRef, rooted: bool, t: ty::t) -> block {
|
||||
if rooted {
|
||||
// NB: v is a raw ptr to an addrspace'd ptr to the value.
|
||||
let v = PointerCast(bcx, Load(bcx, v), type_of(bcx.ccx(), t).ptr_to());
|
||||
drop_ty(bcx, v, t)
|
||||
} else {
|
||||
drop_ty(bcx, v, t)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
|
||||
let _icx = bcx.insn_ctxt("drop_ty_immediate");
|
||||
match ty::get(t).sty {
|
||||
@ -436,8 +428,8 @@ pub fn trans_struct_drop(bcx: block,
|
||||
|
||||
// The second argument is the "self" argument for drop
|
||||
let params = unsafe {
|
||||
lib::llvm::fn_ty_param_tys(
|
||||
llvm::LLVMGetElementType(llvm::LLVMTypeOf(dtor_addr)))
|
||||
let ty = Type::from_ref(llvm::LLVMTypeOf(dtor_addr));
|
||||
ty.element_type().func_params()
|
||||
};
|
||||
|
||||
// Class dtors have no explicit args, so the params should
|
||||
@ -617,20 +609,6 @@ pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) {
|
||||
}
|
||||
|
||||
|
||||
// Chooses the addrspace for newly declared types.
|
||||
pub fn declare_tydesc_addrspace(ccx: &CrateContext, t: ty::t) -> addrspace {
|
||||
if !ty::type_needs_drop(ccx.tcx, t) {
|
||||
return default_addrspace;
|
||||
} else if ty::type_is_immediate(t) {
|
||||
// For immediate types, we don't actually need an addrspace, because
|
||||
// e.g. boxed types include pointers to their contents which are
|
||||
// already correctly tagged with addrspaces.
|
||||
return default_addrspace;
|
||||
} else {
|
||||
return (ccx.next_addrspace)();
|
||||
}
|
||||
}
|
||||
|
||||
// Generates the declaration for (but doesn't emit) a type descriptor.
|
||||
pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
|
||||
// If emit_tydescs already ran, then we shouldn't be creating any new
|
||||
@ -640,20 +618,18 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
|
||||
let llty = type_of(ccx, t);
|
||||
|
||||
if ccx.sess.count_type_sizes() {
|
||||
io::println(fmt!("%u\t%s",
|
||||
llsize_of_real(ccx, llty),
|
||||
io::println(fmt!("%u\t%s", llsize_of_real(ccx, llty),
|
||||
ppaux::ty_to_str(ccx.tcx, t)));
|
||||
}
|
||||
|
||||
let llsize = llsize_of(ccx, llty);
|
||||
let llalign = llalign_of(ccx, llty);
|
||||
let addrspace = declare_tydesc_addrspace(ccx, t);
|
||||
let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc").to_managed();
|
||||
note_unique_llvm_symbol(ccx, name);
|
||||
debug!("+++ declare_tydesc %s %s", ppaux::ty_to_str(ccx.tcx, t), name);
|
||||
let gvar = str::as_c_str(name, |buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf)
|
||||
}
|
||||
});
|
||||
let inf = @mut tydesc_info {
|
||||
@ -661,7 +637,6 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
|
||||
tydesc: gvar,
|
||||
size: llsize,
|
||||
align: llalign,
|
||||
addrspace: addrspace,
|
||||
take_glue: None,
|
||||
drop_glue: None,
|
||||
free_glue: None,
|
||||
@ -706,7 +681,11 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext,
|
||||
let llty = type_of(ccx, t);
|
||||
let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to());
|
||||
helper(bcx, llrawptr0, t);
|
||||
finish_fn(fcx, lltop);
|
||||
|
||||
// This is from the general finish fn, but that emits a ret {} that we don't want
|
||||
Br(raw_block(fcx, false, fcx.llstaticallocas), lltop);
|
||||
RetVoid(raw_block(fcx, false, fcx.llreturn));
|
||||
|
||||
return llfn;
|
||||
}
|
||||
|
||||
@ -732,7 +711,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
||||
//let _icx = ccx.insn_ctxt("emit_tydescs");
|
||||
// As of this point, allow no more tydescs to be created.
|
||||
ccx.finished_tydescs = true;
|
||||
let glue_fn_ty = T_generic_glue_fn(ccx).ptr_to();
|
||||
let glue_fn_ty = Type::generic_glue_fn(ccx);
|
||||
let tyds = &mut ccx.tydescs;
|
||||
for tyds.each_value |&val| {
|
||||
let ti = val;
|
||||
@ -747,7 +726,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
||||
Some(v) => {
|
||||
unsafe {
|
||||
ccx.stats.n_real_glues += 1u;
|
||||
llvm::LLVMConstPointerCast(v, glue_fn_ty)
|
||||
llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref())
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -757,7 +736,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
||||
Some(v) => {
|
||||
unsafe {
|
||||
ccx.stats.n_real_glues += 1u;
|
||||
llvm::LLVMConstPointerCast(v, glue_fn_ty)
|
||||
llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref())
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -767,7 +746,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
||||
Some(v) => {
|
||||
unsafe {
|
||||
ccx.stats.n_real_glues += 1u;
|
||||
llvm::LLVMConstPointerCast(v, glue_fn_ty)
|
||||
llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref())
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -777,16 +756,16 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
||||
Some(v) => {
|
||||
unsafe {
|
||||
ccx.stats.n_real_glues += 1u;
|
||||
llvm::LLVMConstPointerCast(v, glue_fn_ty)
|
||||
llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let shape = C_null(Type::i8p());
|
||||
let shape_tables = C_null(Type::i8p());
|
||||
|
||||
let tydesc =
|
||||
C_named_struct(ccx.tydesc_type,
|
||||
let tydesc = C_named_struct(ccx.tydesc_type,
|
||||
[ti.size, // size
|
||||
ti.align, // align
|
||||
take_glue, // take_glue
|
||||
@ -802,18 +781,11 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
||||
llvm::LLVMSetGlobalConstant(gvar, True);
|
||||
lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage);
|
||||
|
||||
// Index tydesc by addrspace.
|
||||
if ti.addrspace > gc_box_addrspace {
|
||||
let llty = ccx.tydesc_type.ptr_to();
|
||||
let addrspace_name = fmt!("_gc_addrspace_metadata_%u",
|
||||
ti.addrspace as uint);
|
||||
let addrspace_gvar = str::as_c_str(addrspace_name, |buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
|
||||
});
|
||||
lib::llvm::SetLinkage(addrspace_gvar,
|
||||
lib::llvm::InternalLinkage);
|
||||
llvm::LLVMSetInitializer(addrspace_gvar, gvar);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn type_of_glue_fn(ccx: &CrateContext) -> Type {
|
||||
let tydescpp = ccx.tydesc_type.ptr_to().ptr_to();
|
||||
Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], &Type::void())
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ use middle::trans::type_of;
|
||||
use middle::ty;
|
||||
use util::ppaux::ty_to_str;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
// ______________________________________________________________________
|
||||
// compute sizeof / alignof
|
||||
|
||||
@ -140,7 +142,7 @@ pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint {
|
||||
|
||||
debug!("static_size_of_enum: variant %s type %s",
|
||||
cx.tcx.sess.str_of(variant.name),
|
||||
cx.tn.type_to_str(T_struct(lltypes, false)));
|
||||
cx.tn.type_to_str(Type::struct_(lltypes, false)));
|
||||
|
||||
let this_size = llsize_of_real(cx, Type::struct_(lltypes, false));
|
||||
if max_size < this_size {
|
||||
|
@ -30,6 +30,8 @@ use middle::typeck;
|
||||
use util::common::indenter;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use syntax::ast_map::{path, path_mod, path_name};
|
||||
@ -463,7 +465,7 @@ pub fn trans_monomorphized_callee(bcx: block,
|
||||
|
||||
// create a llvalue that represents the fn ptr
|
||||
let fn_ty = node_id_type(bcx, callee_id);
|
||||
let llfn_ty = type_of_fn_from_ty(ccx, fn_ty).to_ptr();
|
||||
let llfn_ty = type_of_fn_from_ty(ccx, fn_ty).ptr_to();
|
||||
let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty);
|
||||
|
||||
// combine the self environment with the rest
|
||||
@ -778,7 +780,7 @@ pub fn make_vtable(ccx: @mut CrateContext,
|
||||
let tbl = C_struct(components);
|
||||
let vtable = ccx.sess.str_of((ccx.names)("vtable"));
|
||||
let vt_gvar = do str::as_c_str(vtable) |buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
|
||||
};
|
||||
llvm::LLVMSetInitializer(vt_gvar, tbl);
|
||||
llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True);
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use back::link::mangle_internal_name_by_path_and_seq;
|
||||
use lib::llvm::{Type, ValueRef, llvm};
|
||||
use lib::llvm::{ValueRef, llvm};
|
||||
use middle::trans::adt;
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::build::*;
|
||||
@ -33,6 +33,8 @@ use syntax::ast;
|
||||
use syntax::ast_map::path_name;
|
||||
use syntax::parse::token::special_idents;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
pub struct Reflector {
|
||||
visitor_val: ValueRef,
|
||||
visitor_methods: @~[@ty::Method],
|
||||
|
@ -17,6 +17,8 @@ use lib::llvm::{True, ModuleRef, ValueRef};
|
||||
use middle::trans::common::*;
|
||||
use middle::trans;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::str;
|
||||
|
||||
pub struct Ctxt {
|
||||
@ -32,7 +34,7 @@ pub fn mk_global(ccx: &CrateContext,
|
||||
-> ValueRef {
|
||||
unsafe {
|
||||
let llglobal = do str::as_c_str(name) |buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf)
|
||||
};
|
||||
llvm::LLVMSetInitializer(llglobal, llval);
|
||||
llvm::LLVMSetGlobalConstant(llglobal, True);
|
||||
@ -50,7 +52,7 @@ pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt {
|
||||
unsafe {
|
||||
let llshapetablesty = Type::named_struct("shapes");
|
||||
do "shapes".as_c_str |buf| {
|
||||
llvm::LLVMAddGlobal(llmod, llshapetablesty, buf)
|
||||
llvm::LLVMAddGlobal(llmod, llshapetablesty.to_ref(), buf)
|
||||
};
|
||||
|
||||
Ctxt {
|
||||
|
@ -27,6 +27,8 @@ use middle::ty;
|
||||
use util::common::indenter;
|
||||
use util::ppaux::ty_to_str;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use core::option::None;
|
||||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
|
@ -11,6 +11,7 @@
|
||||
use core::prelude::*;
|
||||
|
||||
use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind};
|
||||
use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
|
||||
|
||||
use middle::ty;
|
||||
|
||||
@ -26,6 +27,7 @@ use core::cast;
|
||||
|
||||
use core::libc::{c_uint};
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub struct Type {
|
||||
priv rf: TypeRef
|
||||
}
|
||||
@ -38,12 +40,14 @@ macro_rules! ty (
|
||||
* Wrapper for LLVM TypeRef
|
||||
*/
|
||||
impl Type {
|
||||
#[inline(always)]
|
||||
pub fn from_ref(r: TypeRef) -> Type {
|
||||
Type {
|
||||
rf: r
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler
|
||||
pub fn to_ref(&self) -> TypeRef {
|
||||
self.rf
|
||||
}
|
||||
@ -136,7 +140,7 @@ impl Type {
|
||||
|
||||
pub fn float_from_ty(ctx: &CrateContext, t: ast::float_ty) -> Type {
|
||||
match t {
|
||||
ast::ty_f => ctx.float_ty,
|
||||
ast::ty_f => ctx.float_type,
|
||||
ast::ty_f32 => Type::f32(),
|
||||
ast::ty_f64 => Type::f64()
|
||||
}
|
||||
@ -147,7 +151,7 @@ impl Type {
|
||||
}
|
||||
|
||||
pub fn func(args: &[Type], ret: &Type) -> Type {
|
||||
let vec : &[TypeRef] = unsafe { cast::transmute() };
|
||||
let vec : &[TypeRef] = unsafe { cast::transmute(args) };
|
||||
ty!(llvm::LLVMFunctionType(ret.to_ref(), vec::raw::to_ptr(vec),
|
||||
args.len() as c_uint, False))
|
||||
}
|
||||
@ -157,12 +161,13 @@ impl Type {
|
||||
}
|
||||
|
||||
pub fn ptr(ty: Type) -> Type {
|
||||
ty!(llvm::LLVMPointerType(ty, 0 as c_uint))
|
||||
ty!(llvm::LLVMPointerType(ty.to_ref(), 0 as c_uint))
|
||||
}
|
||||
|
||||
pub fn struct_(els: &[Type], packed: bool) -> Type {
|
||||
let els : &[TypeRef] = unsafe { cast::transmute(els) };
|
||||
ty!(llvm::LLVMStructType(vec::raw::to_ptr(els), els.len() as c_uint, packed as Bool))
|
||||
ty!(llvm::LLVMStructTypeInContext(base::task_llcx(), vec::raw::to_ptr(els),
|
||||
els.len() as c_uint, packed as Bool))
|
||||
}
|
||||
|
||||
pub fn named_struct(name: &str) -> Type {
|
||||
@ -175,7 +180,7 @@ impl Type {
|
||||
}
|
||||
|
||||
pub fn vtable() -> Type {
|
||||
Type::array(Type::i8().ptr_to(), 1)
|
||||
Type::array(&Type::i8().ptr_to(), 1)
|
||||
}
|
||||
|
||||
pub fn generic_glue_fn(cx: &mut CrateContext) -> Type {
|
||||
@ -185,7 +190,7 @@ impl Type {
|
||||
}
|
||||
|
||||
let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue);
|
||||
cx.tn.associate_type("glue_fn", ty);
|
||||
cx.tn.associate_type("glue_fn", &ty);
|
||||
|
||||
return ty;
|
||||
}
|
||||
@ -193,10 +198,9 @@ impl Type {
|
||||
pub fn tydesc(arch: Architecture) -> Type {
|
||||
let mut tydesc = Type::named_struct("tydesc");
|
||||
let tydescpp = tydesc.ptr_to().ptr_to();
|
||||
let pvoid = Type::i8().ptr_to();
|
||||
let glue_fn_ty = Type::func(
|
||||
[ Type::nil.ptr_to(), tydescpp, pvoid ],
|
||||
Type::void()).ptr_to();
|
||||
let pvoid = Type::i8p();
|
||||
let glue_fn_ty = Type::func([ Type::nil().ptr_to(), tydescpp, pvoid ],
|
||||
&Type::void()).ptr_to();
|
||||
|
||||
let int_ty = Type::int(arch);
|
||||
|
||||
@ -226,7 +230,7 @@ impl Type {
|
||||
}
|
||||
|
||||
pub fn opaque_vec(arch: Architecture) -> Type {
|
||||
Type::vec(arch, Type::i8())
|
||||
Type::vec(arch, &Type::i8())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -242,11 +246,11 @@ impl Type {
|
||||
}
|
||||
|
||||
pub fn box(ctx: &CrateContext, ty: &Type) -> Type {
|
||||
Type::struct_(Type::box_header_fields(ctx) + [ty], false)
|
||||
Type::struct_(Type::box_header_fields(ctx) + [*ty], false)
|
||||
}
|
||||
|
||||
pub fn opaque_box(ctx: &CrateContext) -> Type {
|
||||
Type::box(ctx, Type::i8())
|
||||
Type::box(ctx, &Type::i8())
|
||||
}
|
||||
|
||||
pub fn unique(ctx: &CrateContext, ty: &Type) -> Type {
|
||||
@ -254,7 +258,7 @@ impl Type {
|
||||
}
|
||||
|
||||
pub fn opaque_cbox_ptr(cx: &CrateContext) -> Type {
|
||||
Type::opaque_box().ptr_to()
|
||||
Type::opaque_box(cx).ptr_to()
|
||||
}
|
||||
|
||||
pub fn enum_discrim(cx: &CrateContext) -> Type {
|
||||
@ -275,7 +279,7 @@ impl Type {
|
||||
}
|
||||
ty::UniqTraitStore => {
|
||||
Type::struct_(
|
||||
[ tydesc_ptr, Type::unique(ctx, Type::i8()).ptr_to()],
|
||||
[ tydesc_ptr, Type::unique(ctx, &Type::i8()).ptr_to()],
|
||||
false)
|
||||
}
|
||||
ty::RegionTraitStore(*) => {
|
||||
@ -301,7 +305,7 @@ impl Type {
|
||||
}
|
||||
|
||||
pub fn ptr_to(&self) -> Type {
|
||||
ty!(llvm::LLVMPointerType(self.to_ref()))
|
||||
ty!(llvm::LLVMPointerType(self.to_ref(), 0))
|
||||
}
|
||||
|
||||
pub fn get_field(&self, idx: uint) -> Type {
|
||||
@ -335,14 +339,38 @@ impl Type {
|
||||
|
||||
pub fn field_types(&self) -> ~[Type] {
|
||||
unsafe {
|
||||
let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint;
|
||||
let n_elts = llvm::LLVMCountStructElementTypes(self.to_ref()) as uint;
|
||||
if n_elts == 0 {
|
||||
return ~[];
|
||||
}
|
||||
let mut elts = vec::from_elem(n_elts, 0 as TypeRef);
|
||||
llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]);
|
||||
llvm::LLVMGetStructElementTypes(self.to_ref(), &mut elts[0]);
|
||||
cast::transmute(elts)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn return_type(&self) -> Type {
|
||||
unsafe {
|
||||
ty!(llvm::LLVMGetReturnType(self.to_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn func_params(&self) -> ~[Type] {
|
||||
unsafe {
|
||||
let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as uint;
|
||||
let args = vec::from_elem(n_args, 0 as TypeRef);
|
||||
llvm::LLVMGetParamTypes(self.to_ref(), vec::raw::to_ptr(args));
|
||||
cast::transmute(args)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn float_width(&self) -> uint {
|
||||
match self.kind() {
|
||||
Float => 32,
|
||||
Double => 64,
|
||||
X86_FP80 => 80,
|
||||
FP128 | PPC_FP128 => 128,
|
||||
_ => fail!("llvm_float_width called on a non-float type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ use middle::trans::common;
|
||||
use middle::ty;
|
||||
use util::ppaux;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use syntax::ast;
|
||||
|
||||
pub fn arg_is_indirect(_: &CrateContext, arg_ty: &ty::t) -> bool {
|
||||
@ -58,10 +60,15 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t)
|
||||
atys.push_all(type_of_explicit_args(cx, inputs));
|
||||
|
||||
// Use the output as the actual return value if it's immediate.
|
||||
<<<<<<< HEAD
|
||||
if output_is_immediate && !ty::type_is_nil(output) {
|
||||
Type::func(atys, lloutputtype)
|
||||
=======
|
||||
if output_is_immediate {
|
||||
Type::func(atys, &lloutputtype)
|
||||
>>>>>>> Finish up Type refactoring
|
||||
} else {
|
||||
Type::func(atys, Type::void())
|
||||
Type::func(atys, &Type::void())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,11 +94,11 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||
match ty::get(t).sty {
|
||||
ty::ty_box(mt) => {
|
||||
let ty = type_of(cx, mt.ty);
|
||||
Type::box(cx, ty).ptr_to()
|
||||
Type::box(cx, &ty).ptr_to()
|
||||
}
|
||||
ty::ty_uniq(mt) => {
|
||||
let ty = type_of(cx, mt.ty);
|
||||
Type::unique(cx, ty).ptr_to()
|
||||
Type::unique(cx, &ty).ptr_to()
|
||||
}
|
||||
_ => {
|
||||
cx.sess.bug("non-box in type_of_non_gc_box");
|
||||
@ -146,14 +153,14 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||
ty::ty_closure(*) => Type::struct_([Type::i8p(), Type::i8p()], false),
|
||||
ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store),
|
||||
|
||||
ty::ty_estr(ty::vstore_fixed(size)) => Type::array(Type::i8(), size),
|
||||
ty::ty_estr(ty::vstore_fixed(size)) => Type::array(&Type::i8(), size as u64),
|
||||
ty::ty_evec(mt, ty::vstore_fixed(size)) => {
|
||||
Type::array(sizing_type_of(cx, mt.ty), size)
|
||||
Type::array(&sizing_type_of(cx, mt.ty), size as u64)
|
||||
}
|
||||
|
||||
ty::ty_unboxed_vec(mt) => {
|
||||
let sz_ty = sizing_type_of(cx, mt.ty);
|
||||
Type::vec(cx.sess.targ_cfg.arch, sz_ty)
|
||||
Type::vec(cx.sess.targ_cfg.arch, &sz_ty)
|
||||
}
|
||||
|
||||
ty::ty_tup(*) | ty::ty_enum(*) => {
|
||||
@ -165,7 +172,7 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||
if ty::type_is_simd(cx.tcx, t) {
|
||||
let et = ty::simd_type(cx.tcx, t);
|
||||
let n = ty::simd_size(cx.tcx, t);
|
||||
Type::vector(type_of(cx, et), n)
|
||||
Type::vector(&type_of(cx, et), n as u64)
|
||||
} else {
|
||||
let repr = adt::represent_type(cx, t);
|
||||
let packed = ty::lookup_packed(cx.tcx, did);
|
||||
@ -205,14 +212,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||
return llty;
|
||||
}
|
||||
|
||||
let llty = match ty::get(t).sty {
|
||||
let mut llty = match ty::get(t).sty {
|
||||
ty::ty_nil | ty::ty_bot => Type::nil(),
|
||||
ty::ty_bool => Type::bool(),
|
||||
ty::ty_int(t) => Type::int_from_ty(cx, t),
|
||||
ty::ty_uint(t) => Type::uint_from_ty(cx, t),
|
||||
ty::ty_float(t) => Type::float_from_ty(cx, t),
|
||||
ty::ty_estr(ty::vstore_uniq) => {
|
||||
Type::unique(cx, Type::vec(cx.sess.targ_cfg.arch, Type::i8())).ptr_to()
|
||||
Type::unique(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to()
|
||||
}
|
||||
ty::ty_enum(did, ref substs) => {
|
||||
// Only create the named struct, but don't fill it in. We
|
||||
@ -223,30 +230,30 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||
Type::named_struct(llvm_type_name(cx, an_enum, did, substs.tps))
|
||||
}
|
||||
ty::ty_estr(ty::vstore_box) => {
|
||||
Type::box(cx, Type::vec(cx, Type::i8())).ptr_to()
|
||||
Type::box(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to()
|
||||
}
|
||||
ty::ty_evec(ref mt, ty::vstore_box) => {
|
||||
let e_ty = type_of(cx, mt.ty);
|
||||
let v_ty = Type::vec(cx.sess.targ_cfg.arch, e_ty);
|
||||
Type::box(cx, v_ty).ptr_to()
|
||||
let v_ty = Type::vec(cx.sess.targ_cfg.arch, &e_ty);
|
||||
Type::box(cx, &v_ty).ptr_to()
|
||||
}
|
||||
ty::ty_box(ref mt) => {
|
||||
let ty = type_of(cx, mt.ty);
|
||||
Type::box(cx, ty).ptr_to()
|
||||
Type::box(cx, &ty).ptr_to()
|
||||
}
|
||||
ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(),
|
||||
ty::ty_uniq(ref mt) => {
|
||||
let ty = type_of(cx, mt.ty);
|
||||
Type::unique(cx, ty).ptr_to()
|
||||
Type::unique(cx, &ty).ptr_to()
|
||||
}
|
||||
ty::ty_evec(ref mt, ty::vstore_uniq) => {
|
||||
let ty = type_of(cx, mt.ty);
|
||||
let ty = Type::vec(cx, ty);
|
||||
Type::unique(cx, ty).ptr_to()
|
||||
let ty = Type::vec(cx.sess.targ_cfg.arch, &ty);
|
||||
Type::unique(cx, &ty).ptr_to()
|
||||
}
|
||||
ty::ty_unboxed_vec(ref mt) => {
|
||||
let ty = type_of(cx, mt.ty);
|
||||
Type::vec(cx.sess.targ_cfg.arch, ty)
|
||||
Type::vec(cx.sess.targ_cfg.arch, &ty)
|
||||
}
|
||||
ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(),
|
||||
ty::ty_rptr(_, ref mt) => type_of(cx, mt.ty).ptr_to(),
|
||||
@ -263,20 +270,20 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||
}
|
||||
|
||||
ty::ty_estr(ty::vstore_fixed(n)) => {
|
||||
Type::array(Type::i8(), n + 1u /* +1 for trailing null */)
|
||||
Type::array(&Type::i8(), (n + 1u) as u64)
|
||||
}
|
||||
|
||||
ty::ty_evec(ref mt, ty::vstore_fixed(n)) => {
|
||||
Type::array(type_of(cx, mt.ty), n)
|
||||
Type::array(&type_of(cx, mt.ty), n as u64)
|
||||
}
|
||||
|
||||
ty::ty_bare_fn(_) => type_of_fn_from_ty(cx, t).ptr_to(),
|
||||
ty::ty_closure(_) => {
|
||||
let ty = type_of_fn_from_ty(cx, t);
|
||||
Type::func_pair(cx, ty)
|
||||
Type::func_pair(cx, &ty)
|
||||
}
|
||||
ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store),
|
||||
ty::ty_type => cx.tydesc_type.to_ptr(),
|
||||
ty::ty_type => cx.tydesc_type.ptr_to(),
|
||||
ty::ty_tup(*) => {
|
||||
let repr = adt::represent_type(cx, t);
|
||||
Type::struct_(adt::fields_of(cx, repr), false)
|
||||
@ -286,7 +293,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||
if ty::type_is_simd(cx.tcx, t) {
|
||||
let et = ty::simd_type(cx.tcx, t);
|
||||
let n = ty::simd_size(cx.tcx, t);
|
||||
Type::vector(type_of(cx, et), n)
|
||||
Type::vector(&type_of(cx, et), n as u64)
|
||||
} else {
|
||||
// Only create the named struct, but don't fill it in. We fill it
|
||||
// in *after* placing it into the type cache. This prevents
|
||||
@ -306,16 +313,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||
match ty::get(t).sty {
|
||||
ty::ty_enum(*) => {
|
||||
let repr = adt::represent_type(cx, t);
|
||||
common::set_struct_body(llty, adt::fields_of(cx, repr),
|
||||
false);
|
||||
llty.set_struct_body(adt::fields_of(cx, repr), false);
|
||||
}
|
||||
|
||||
ty::ty_struct(did, _) => {
|
||||
if !ty::type_is_simd(cx.tcx, t) {
|
||||
let repr = adt::represent_type(cx, t);
|
||||
let packed = ty::lookup_packed(cx.tcx, did);
|
||||
common::set_struct_body(llty, adt::fields_of(cx, repr),
|
||||
packed);
|
||||
llty.set_struct_body(adt::fields_of(cx, repr), packed);
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
@ -345,19 +350,5 @@ pub fn llvm_type_name(cx: &CrateContext,
|
||||
|
||||
pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> Type {
|
||||
let self_ty = type_of(ccx, self_ty).ptr_to();
|
||||
Type::func([self_ty], Type::viod())
|
||||
Type::func([self_ty], Type::void())
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> Type {
|
||||
let addrspace = base::get_tydesc(ccx, t).addrspace;
|
||||
debug!("type_of_rooted %s in addrspace %u",
|
||||
ppaux::ty_to_str(ccx.tcx, t), addrspace as uint);
|
||||
return T_root(type_of(ccx, t), addrspace);
|
||||
}
|
||||
|
||||
pub fn type_of_glue_fn(ccx: &CrateContext) -> Type {
|
||||
let tydescpp = T_ptr(T_ptr(ccx.tydesc_type));
|
||||
return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_void());
|
||||
}
|
||||
*/
|
||||
|
@ -28,6 +28,8 @@ use middle::ty;
|
||||
use syntax::codemap::span;
|
||||
use syntax::ast;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
pub fn root_and_write_guard(datum: &Datum,
|
||||
mut bcx: block,
|
||||
span: span,
|
||||
|
@ -175,15 +175,15 @@ pub extern "rust-intrinsic" {
|
||||
pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int;
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_umin(dst: &mut int, src: int) -> int;
|
||||
pub fn atomic_umax(dst: &mut int, src: int) -> int;
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_umin_acq(dst: &mut int, src: int) -> int;
|
||||
pub fn atomic_umax_acq(dst: &mut int, src: int) -> int;
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_umin_rel(dst: &mut int, src: int) -> int;
|
||||
pub fn atomic_umax_rel(dst: &mut int, src: int) -> int;
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int;
|
||||
pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int;
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int;
|
||||
pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int;
|
||||
|
||||
/// The size of a type in bytes.
|
||||
///
|
||||
|
Loading…
x
Reference in New Issue
Block a user