提交 81cf72c2 编写于 作者: J James Miller

Finish up Type refactoring

上级 57a75374
......@@ -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 @@ pub struct Upcalls {
)
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 @@ pub fn associate_type(&mut self, s: &str, t: &Type) {
}
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 @@ pub fn find_type(&self, s: &str) -> Option<Type> {
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 @@ pub fn type_to_str(&self, ty: TypeRef) -> ~str {
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 @@ pub fn type_to_str(&self, ty: TypeRef) -> ~str {
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 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::common::*;
use middle::ty;
use middle::trans::type_::Type;
use core::str;
use syntax::ast;
......
......@@ -63,6 +63,8 @@
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 @@ fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef {
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 @@ fn create_entry_fn(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 @@ fn create_entry_fn(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 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 @@ pub fn decl_fn(&self, decl: &fn(fnty: Type) -> ValueRef) -> ValueRef {
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 @@ pub fn build_shim_args(&self,
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 @@ pub fn build_shim_args(&self,
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 @@ pub fn build_shim_ret(&self,
// 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 @@ pub fn build_shim_ret(&self,
};
}
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 @@ pub fn build_wrap_args(&self,
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 @@ pub fn build_wrap_args(&self,
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 @@ pub fn build_wrap_ret(&self,
} 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)
}
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)))
}
_ => fail!("ty_align: unhandled type")
}
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
}
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)
}
_ => 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")
}
}
......@@ -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::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
}
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)
match ty.kind() {
Integer => {
unsafe {
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
}
_ => 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)
}
}
Array => {
let len = ty.array_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
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)
}
_ => 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::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 @@
#[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 @@ fn is_sse(&self) -> bool {
}
}
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 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 => 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
}
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)
}
fn ty_size(ty: Type) -> uint {
match ty.kind() {
Integer => {
unsafe {
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
}
Array => {
let len = ty.array_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
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)
}
_ => 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")
}
}
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 unify(cls: &mut [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: Type,
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: Type,
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 fixup(ty: Type, cls: &mut [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 fixup(ty: Type, cls: &mut [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 fixup(ty: Type, cls: &mut [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 llvec_len(cls: &[RegClass]) -> uint {
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_ty(ty: 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::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::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::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 @@ pub fn unpack(&self, bcx: &mut block) -> ValueRef {
}
}
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 @@ pub fn to_str(&self) -> ~str {
}
}
/*
// 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::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 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 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 @@ pub fn new(sess: session::Session, name: &str, tcx: ty::ctxt,
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 @@ pub fn new(sess: session::Session, name: &str, tcx: ty::ctxt,
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 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 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 get_val(bcx: block, did: ast::def_id, const_ty: ty::t)
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::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::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::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::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 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_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 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 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::libc::{c_uint};
#[deriving(Eq)]
pub struct Type {
priv rf: TypeRef
}
......@@ -38,12 +40,14 @@ pub struct Type {
* 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 @@ pub fn uint_from_ty(ctx: &CrateContext, t: ast::uint_ty) -> 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 @@ pub fn size_t(arch: Architecture) -> 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 @@ pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> 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 @@ pub fn empty_struct() -> 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 @@ pub fn generic_glue_fn(cx: &mut CrateContext) -> 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 @@ pub fn generic_glue_fn(cx: &mut CrateContext) -> 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 @@ pub fn vec(arch: Architecture, ty: &Type) -> Type {
}
pub fn opaque_vec(arch: Architecture) -> Type {
Type::vec(arch, Type::i8())
Type::vec(arch, &Type::i8())
}
#[inline]
......@@ -242,11 +246,11 @@ pub fn box_header(ctx: &CrateContext) -> 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 @@ pub fn unique(ctx: &CrateContext, ty: &Type) -> 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 @@ pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> 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 @@ pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
}
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 @@ pub fn array_length(&self) -> uint {
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::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())
}
/*
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());
Type::func([self_ty], Type::void())
}
*/
......@@ -28,6 +28,8 @@
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 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.
///
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册