From fd83b92b598219d74317406a25234d572de584e0 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 16 Jun 2013 02:29:52 +1200 Subject: [PATCH] More Type refactorings --- src/librustc/back/upcall.rs | 61 ++-- src/librustc/lib/llvm.rs | 12 - src/librustc/middle/trans/_match.rs | 2 +- src/librustc/middle/trans/adt.rs | 32 +- src/librustc/middle/trans/asm.rs | 8 +- src/librustc/middle/trans/base.rs | 465 +++++++++---------------- src/librustc/middle/trans/build.rs | 209 ++++++----- src/librustc/middle/trans/cabi.rs | 18 +- src/librustc/middle/trans/cabi_arm.rs | 65 ++-- src/librustc/middle/trans/cabi_mips.rs | 20 +- src/librustc/middle/trans/common.rs | 32 +- src/librustc/middle/trans/context.rs | 3 +- src/librustc/middle/trans/type_.rs | 121 +++++-- 13 files changed, 470 insertions(+), 578 deletions(-) diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs index 4d2ea4eb4a642..731fa1c0ad79e 100644 --- a/src/librustc/back/upcall.rs +++ b/src/librustc/back/upcall.rs @@ -11,8 +11,8 @@ use driver::session; use middle::trans::base; -use middle::trans::common::{T_fn, T_i8, T_i32, T_int, T_ptr, T_void}; -use lib::llvm::{ModuleRef, ValueRef, TypeRef}; +use middle::trans::type_::Type; +use lib::llvm::{ModuleRef, ValueRef}; pub struct Upcalls { trace: ValueRef, @@ -22,40 +22,35 @@ pub struct Upcalls { reset_stack_limit: ValueRef } -pub fn declare_upcalls(targ_cfg: @session::config, - llmod: ModuleRef) -> @Upcalls { - fn decl(llmod: ModuleRef, prefix: ~str, name: ~str, - tys: ~[TypeRef], rv: TypeRef) -> - ValueRef { - let arg_tys = tys.map(|t| *t); - let fn_ty = T_fn(arg_tys, rv); - return base::decl_cdecl_fn(llmod, prefix + name, fn_ty); - } - fn nothrow(f: ValueRef) -> ValueRef { - base::set_no_unwind(f); f - } - let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef = - |a,b,c| decl(llmod, ~"upcall_", a, b, c); - let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef = - |a,b| decl(llmod, ~"upcall_", a, b, T_void()); +macro_rules! upcall ( + (fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ + 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 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 decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); + base::set_no_unwind(decl); + decl + }) +) - let int_t = T_int(targ_cfg); +pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls { + let opaque_ptr = Type::i8().to_ptr(); + let int_ty = Type::int(targ_cfg.arch); @Upcalls { - trace: dv(~"trace", ~[T_ptr(T_i8()), - T_ptr(T_i8()), - int_t]), - call_shim_on_c_stack: - d(~"call_shim_on_c_stack", - // arguments: void *args, void *fn_ptr - ~[T_ptr(T_i8()), T_ptr(T_i8())], - int_t), + trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()), + call_shim_on_c_stack: upcall!(fn call_shim_on_c_stack(opaque_ptr, opaque_ptr) -> int_ty), call_shim_on_rust_stack: - d(~"call_shim_on_rust_stack", - ~[T_ptr(T_i8()), T_ptr(T_i8())], int_t), - rust_personality: - nothrow(d(~"rust_personality", ~[], T_i32())), - reset_stack_limit: - nothrow(dv(~"reset_stack_limit", ~[])) + upcall!(fn call_shim_on_rust_stack(opaque_ptr, opaque_ptr) -> int_ty), + rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()), + reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void()) } } diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 14f5166b123a7..627474b21892c 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2233,18 +2233,6 @@ pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] { } } -pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] { - unsafe { - let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint; - if n_elts == 0 { - return ~[]; - } - let mut elts = vec::from_elem(n_elts, ptr::null()); - llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]); - return elts; - } -} - /* Memory-managed interface to target data. */ diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 2b46b3b272486..db5a642019c08 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1644,7 +1644,7 @@ fn create_bindings_map(bcx: block, pat: @ast::pat) -> BindingsMap { // but during matching we need to store a *T as explained // above let is_move = ccx.maps.moves_map.contains(&p_id); - llmatch = alloca(bcx, T_ptr(llvariable_ty)); + llmatch = alloca(bcx, llvariable_ty.ptr_to()); trmode = TrByValue(is_move, alloca(bcx, llvariable_ty)); } ast::bind_by_ref(_) => { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 79b5aba227c39..65163e384b1fb 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -49,7 +49,7 @@ use core::libc::c_ulonglong; use core::option::{Option, Some, None}; use core::vec; -use lib::llvm::{ValueRef, TypeRef, True, IntEQ, IntNE}; +use lib::llvm::{ValueRef, True, IntEQ, IntNE}; use middle::trans::_match; use middle::trans::build::*; use middle::trans::common::*; @@ -212,7 +212,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct { let lltys = tys.map(|&ty| type_of::sizing_type_of(cx, ty)); - let llty_rec = T_struct(lltys, packed); + let llty_rec = Type::struct_(lltys, packed); Struct { size: machine::llsize_of_alloc(cx, llty_rec) /*bad*/as u64, align: machine::llalign_of_min(cx, llty_rec) /*bad*/as u64, @@ -226,17 +226,16 @@ fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct { * All nominal types are LLVM structs, in order to be able to use * forward-declared opaque types to prevent circularity in `type_of`. */ -pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[TypeRef] { +pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] { generic_fields_of(cx, r, false) } /// Like `fields_of`, but for `type_of::sizing_type_of` (q.v.). -pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[TypeRef] { +pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] { generic_fields_of(cx, r, true) } -fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) - -> ~[TypeRef] { +fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { match *r { - CEnum(*) => ~[T_enum_discrim(cx)], + CEnum(*) => ~[Type::enum_discrim(cx)], Univariant(ref st, _dtor) => struct_llfields(cx, st, sizing), NullablePointer{ nonnull: ref st, _ } => struct_llfields(cx, st, sizing), General(ref sts) => { @@ -261,14 +260,15 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) let most_aligned = most_aligned.get(); let padding = largest_size - most_aligned.size; + assert!(padding >= 0); + struct_llfields(cx, most_aligned, sizing) - + [T_array(T_i8(), padding /*bad*/as uint)] + + [Type::array(Type::i8(), padding /*bad*/as uint)] } } } -fn struct_llfields(cx: &mut CrateContext, st: &Struct, sizing: bool) - -> ~[TypeRef] { +fn struct_llfields(cx: &mut CrateContext, st: &Struct, sizing: bool) -> ~[Type] { if sizing { st.fields.map(|&ty| type_of::sizing_type_of(cx, ty)) } else { @@ -309,7 +309,7 @@ pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef) (cases.len() - 1) as int), NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => { ZExt(bcx, nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee), - T_enum_discrim(bcx.ccx())) + Type::enum_discrim(bcx.ccx())) } } } @@ -438,11 +438,11 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int, } else { // The unit-like case might have a nonzero number of unit-like fields. // (e.g., Result or Either with () as one side.) - let llty = type_of::type_of(bcx.ccx(), nullfields[ix]); + let ty = type_of::type_of(bcx.ccx(), nullfields[ix]); assert_eq!(machine::llsize_of_alloc(bcx.ccx(), llty), 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, T_ptr(llty)) + PointerCast(bcx, val, ty.ptr_to()) } } } @@ -456,8 +456,8 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint, let fields = do st.fields.map |&ty| { type_of::type_of(ccx, ty) }; - let real_llty = T_struct(fields, st.packed); - PointerCast(bcx, val, T_ptr(real_llty)) + let real_ty = Type::struct_(fields, st.packed); + PointerCast(bcx, val, real_llty.to_ptr().to_ref()) } else { val }; @@ -572,7 +572,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef]) } fn padding(size: u64) -> ValueRef { - C_undef(T_array(T_i8(), size /*bad*/as uint)) + C_undef(Type::array(Type::i8(), size).to_ref()) } // XXX this utility routine should be somewhere more general diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 3814ff319f2dc..17294107ce367 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -110,11 +110,11 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { // Depending on how many outputs we have, the return type is different let output = if numOutputs == 0 { - T_void() + Type::void() } else if numOutputs == 1 { val_ty(outputs[0]) } else { - T_struct(outputs.map(|o| val_ty(*o)), false) + Type::struct_(outputs.map(|o| val_ty(*o)), false) }; let dialect = match ia.dialect { @@ -130,12 +130,12 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { // Again, based on how many outputs we have if numOutputs == 1 { - let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0]))); + let op = PointerCast(bcx, aoutputs[0], val_ty(outputs[0]).ptr_to()); Store(bcx, r, op); } else { for aoutputs.iter().enumerate().advance |(i, o)| { let v = ExtractValue(bcx, r, i); - let op = PointerCast(bcx, *o, T_ptr(val_ty(outputs[i]))); + let op = PointerCast(bcx, *o, val_ty(outputs[i]).ptr_to()); Store(bcx, v, op); } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 18d87b46e1935..de91a9c593a53 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -29,7 +29,7 @@ use back::link::{mangle_exported_name}; use back::{link, abi}; use driver::session; use driver::session::Session; -use lib::llvm::{ContextRef, ModuleRef, ValueRef, TypeRef, BasicBlockRef}; +use lib::llvm::{ContextRef, ModuleRef, ValueRef, BasicBlockRef}; use lib::llvm::{llvm, True, False}; use lib; use metadata::common::LinkMeta; @@ -138,42 +138,33 @@ fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { } } -pub fn decl_fn(llmod: ModuleRef, - name: &str, - cc: lib::llvm::CallConv, - llty: TypeRef) - -> ValueRef { - let llfn: ValueRef = str::as_c_str(name, |buf| { +pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef { + let llfn: ValueRef = do name.as_c_str |buf| { unsafe { - llvm::LLVMGetOrInsertFunction(llmod, buf, llty) + llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref()) } - }); + }; lib::llvm::SetFunctionCallConv(llfn, cc); return llfn; } -pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, llty: TypeRef) - -> ValueRef { +pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef { return decl_fn(llmod, name, lib::llvm::CCallConv, llty); } // Only use this if you are going to actually define the function. It's // not valid to simply declare a function as internal. -pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) -> - ValueRef { - let llfn = decl_cdecl_fn(llmod, name, llty); +pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, ty: Type) -> ValueRef { + let llfn = decl_cdecl_fn(llmod, name, ty); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); return llfn; } -pub fn get_extern_fn(externs: &mut ExternMap, - llmod: ModuleRef, - name: @str, - cc: lib::llvm::CallConv, - ty: TypeRef) -> ValueRef { - match externs.find(&name) { - Some(n) => return copy *n, +pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: @str, + cc: lib::llvm::CallConv, ty: Type) -> ValueRef { + match externs.find_copy(&name) { + Some(n) => return n, None => () } let f = decl_fn(llmod, name, cc, ty); @@ -182,43 +173,19 @@ pub fn get_extern_fn(externs: &mut ExternMap, } pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef, - name: @str, ty: TypeRef) -> ValueRef { - match externs.find(&name) { - Some(n) => return copy *n, + name: @str, ty: Type) -> ValueRef { + match externs.find_copy(&name) { + Some(n) => return n, None => () } unsafe { - let c = str::as_c_str(name, |buf| { - llvm::LLVMAddGlobal(llmod, ty, buf) - }); + let c = do name.as_c_str |buf| { + llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf) + }; externs.insert(name, c); return c; } } - -fn get_simple_extern_fn(cx: block, - externs: &mut ExternMap, - llmod: ModuleRef, - name: @str, - n_args: int) -> ValueRef { - let _icx = cx.insn_ctxt("get_simple_extern_fn"); - let ccx = cx.fcx.ccx; - let inputs = vec::from_elem(n_args as uint, ccx.int_type); - let output = ccx.int_type; - let t = T_fn(inputs, output); - return get_extern_fn(externs, llmod, name, lib::llvm::CCallConv, t); -} - -pub fn trans_foreign_call(cx: block, externs: &mut ExternMap, - llmod: ModuleRef, name: @str, args: &[ValueRef]) -> - ValueRef { - let _icx = cx.insn_ctxt("trans_foreign_call"); - let n = args.len() as int; - let llforeign: ValueRef = - get_simple_extern_fn(cx, externs, llmod, name, n); - return Call(cx, llforeign, args); -} - pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { let _icx = cx.insn_ctxt("umax"); let cond = ICmp(cx, lib::llvm::IntULT, a, b); @@ -236,7 +203,7 @@ pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { // return type, use bump_ptr(). pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef { let _icx = bcx.insn_ctxt("ptr_offs"); - let raw = PointerCast(bcx, base, T_ptr(T_i8())); + let raw = PointerCast(bcx, base, Type::i8p()); InBoundsGEP(bcx, raw, [sz]) } @@ -247,7 +214,7 @@ pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) -> let _icx = bcx.insn_ctxt("bump_ptr"); let ccx = bcx.ccx(); let bumped = ptr_offs(bcx, base, sz); - let typ = T_ptr(type_of(ccx, t)); + let typ = type_of(ccx, t).ptr_to(); PointerCast(bcx, bumped, typ) } @@ -262,8 +229,8 @@ 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 = T_box(ccx, ty); - let boxptr = PointerCast(bcx, boxptr, T_ptr(ty)); + let ty = Type::box(ccx, ty); + let boxptr = PointerCast(bcx, boxptr, ty.ptr_to()); GEPi(bcx, boxptr, [0u, abi::box_field_body]) } @@ -294,8 +261,8 @@ pub fn malloc_raw_dyn(bcx: block, glue::lazily_emit_all_tydesc_glue(ccx, static_ti); // Allocate space: - let tydesc = PointerCast(bcx, static_ti.tydesc, T_ptr(T_i8())); - let rval = alloca(bcx, T_ptr(T_i8())); + let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p()); + let rval = alloca(bcx, Type::i8p()); let bcx = callee::trans_lang_call( bcx, langcall, @@ -320,7 +287,7 @@ pub fn non_gc_box_cast(bcx: block, val: ValueRef) -> ValueRef { add_comment(bcx, "non_gc_box_cast"); assert!(llvm::LLVMGetPointerAddressSpace(val_ty(val)) == gc_box_addrspace || bcx.unreachable); - let non_gc_t = T_ptr(llvm::LLVMGetElementType(val_ty(val))); + let non_gc_t = llvm::LLVMGetElementType(val_ty(val)).ptr_to(); PointerCast(bcx, val, non_gc_t) } } @@ -760,8 +727,8 @@ pub fn cast_shift_const_rhs(op: ast::binop, pub fn cast_shift_rhs(op: ast::binop, lhs: ValueRef, rhs: ValueRef, - trunc: &fn(ValueRef, TypeRef) -> ValueRef, - zext: &fn(ValueRef, TypeRef) -> ValueRef) + trunc: &fn(ValueRef, Type) -> ValueRef, + zext: &fn(ValueRef, Type) -> ValueRef) -> ValueRef { // Shifts may have any size int on the rhs unsafe { @@ -794,11 +761,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(T_int_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(T_uint_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) } _ => { @@ -812,7 +779,7 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop, } pub fn null_env_ptr(bcx: block) -> ValueRef { - C_null(T_opaque_box_ptr(bcx.ccx())) + C_null(Type::opaque_box(bcx.ccx()).to_ptr()) } pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t) @@ -835,7 +802,7 @@ pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) -> (ValueRef, block) { let _icx = bcx.insn_ctxt("invoke_"); if bcx.unreachable { - return (C_null(T_i8()), bcx); + return (C_null(Type::i8()), bcx); } match bcx.node_info { @@ -968,7 +935,7 @@ pub fn get_landing_pad(bcx: block) -> BasicBlockRef { // The landing pad return type (the type being propagated). Not sure what // this represents but it's determined by the personality function and // this is what the EH proposal example uses. - let llretty = T_struct([T_ptr(T_i8()), T_i32()], false); + let llretty = Type::struct_([Type::i8p(), Type::i32()], false); // The exception handling personality function. This is the C++ // personality function __gxx_personality_v0, wrapped in our naming // convention. @@ -1026,7 +993,7 @@ pub fn find_bcx_for_scope(bcx: block, scope_id: ast::node_id) -> block { pub fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef { if ty::type_is_bot(t) { - return C_null(T_ptr(T_i8())); + return C_null(Type::i8p()); } let llptr = alloc_ty(bcx, t); Store(bcx, v, llptr); @@ -1069,8 +1036,8 @@ pub fn trans_trace(bcx: block, sp_opt: Option, trace_str: @str) { } }; let ccx = bcx.ccx(); - let V_trace_str = PointerCast(bcx, V_trace_str, T_ptr(T_i8())); - let V_filename = PointerCast(bcx, V_filename, T_ptr(T_i8())); + let V_trace_str = PointerCast(bcx, V_trace_str, Type::i8p()); + let V_filename = PointerCast(bcx, V_filename, Type::i8p()); let args = ~[V_trace_str, V_filename, C_int(ccx, V_line)]; Call(bcx, ccx.upcalls.trace, args); } @@ -1466,8 +1433,8 @@ pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a X86_64 => "llvm.memcpy.p0i8.p0i8.i64" }; let memcpy = ccx.intrinsics.get_copy(&key); - let src_ptr = PointerCast(cx, src, T_ptr(T_i8())); - let dst_ptr = PointerCast(cx, dst, T_ptr(T_i8())); + let src_ptr = PointerCast(cx, src, Type::i8p()); + let dst_ptr = PointerCast(cx, dst, Type::i8p()); let size = IntCast(cx, n_bytes, ccx.int_type); let align = C_i32(align as i32); let volatile = C_i1(false); @@ -1510,10 +1477,10 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { }; let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key); - let llptr = PointerCast(cx, llptr, T_ptr(T_i8())); + let llptr = PointerCast(cx, llptr, Type::i8().ptr_to()); let llzeroval = C_u8(0); - let size = IntCast(cx, machine::llsize_of(ccx, llty), ccx.int_type); - let align = C_i32(llalign_of_min(ccx, llty) as i32); + let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type.to_ref()); + let align = C_i32(llalign_of_min(ccx, ty) as i32); let volatile = C_i1(false); Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]); } @@ -1521,39 +1488,37 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { pub fn alloc_ty(bcx: block, t: ty::t) -> ValueRef { let _icx = bcx.insn_ctxt("alloc_ty"); let ccx = bcx.ccx(); - let llty = type_of::type_of(ccx, t); - if ty::type_has_params(t) { debug!("%s", ty_to_str(ccx.tcx, t)); } - assert!(!ty::type_has_params(t)); - let val = alloca(bcx, llty); + let ty = type_of::type_of(ccx, t); + assert!(!ty::type_has_params(t), "Type has params: %s", ty_to_str(ccx.tcx, t)); + let val = alloca(bcx, ty); return val; } -pub fn alloca(cx: block, t: TypeRef) -> ValueRef { - alloca_maybe_zeroed(cx, t, false) +pub fn alloca(cx: block, ty: Type) -> ValueRef { + alloca_maybe_zeroed(cx, ty, false) } pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef { let _icx = cx.insn_ctxt("alloca"); if cx.unreachable { unsafe { - return llvm::LLVMGetUndef(t); + return llvm::LLVMGetUndef(ty.to_ref()); } } let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas); - let p = Alloca(initcx, t); - if zero { memzero(initcx, p, t); } - return p; + let p = Alloca(initcx, ty.to_ref()); + if zero { memzero(initcx, p, ty); } + p } pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef { let _icx = cx.insn_ctxt("arrayalloca"); if cx.unreachable { unsafe { - return llvm::LLVMGetUndef(t); + return llvm::LLVMGetUndef(ty); } } - return ArrayAlloca( - base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), t, v); + return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty.to_ref(), v); } pub struct BasicBlocks { @@ -1623,7 +1588,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, let fcx = @mut fn_ctxt_ { llfn: llfndecl, llenv: unsafe { - llvm::LLVMGetUndef(T_ptr(T_i8())) + llvm::LLVMGetUndef(Type::i8p()) }, llretptr: None, llstaticallocas: llbbs.sa, @@ -1741,7 +1706,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, Store(bcx, tmp, alloc); alloc } else { - PointerCast(bcx, slf.v, T_ptr(type_of(bcx.ccx(), slf.t))) + PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()) }; fcx.llself = Some(ValSelfData {v: self_val, ..slf}); @@ -2268,7 +2233,7 @@ pub fn register_fn_fuller(ccx: @mut CrateContext, attrs: &[ast::attribute], node_type: ty::t, cc: lib::llvm::CallConv, - llfty: TypeRef) + fn_ty: Type) -> ValueRef { debug!("register_fn_fuller creating fn for item %d with path %s", node_id, @@ -2280,12 +2245,11 @@ pub fn register_fn_fuller(ccx: @mut CrateContext, mangle_exported_name(ccx, /*bad*/copy path, node_type) }; - let llfn: ValueRef = decl_fn(ccx.llmod, ps, cc, llfty); + let llfn = decl_fn(ccx.llmod, ps, cc, fn_ty); ccx.item_symbols.insert(node_id, ps); // FIXME #4404 android JNI hacks - let is_entry = is_entry_fn(&ccx.sess, node_id) && - (!*ccx.sess.building_library || + let is_entry = is_entry_fn(&ccx.sess, node_id) && (!*ccx.sess.building_library || (*ccx.sess.building_library && ccx.sess.targ_cfg.os == session::os_android)); if is_entry { @@ -2345,7 +2309,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 = T_fn([ccx.int_type, T_ptr(T_ptr(T_i8()))], 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 { @@ -2376,7 +2340,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, let crate_map = ccx.crate_map; let opaque_crate_map = llvm::LLVMBuildPointerCast(bld, crate_map, - T_ptr(T_i8()), + Type::i8p(), noname()); let (start_fn, args) = if use_start_lang_item { @@ -2391,10 +2355,10 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, let args = { let opaque_rust_main = llvm::LLVMBuildPointerCast( - bld, rust_main, T_ptr(T_i8()), noname()); + bld, rust_main, Type::i8p(), noname()); ~[ - C_null(T_opaque_box_ptr(ccx)), + C_null(Type::opaque_box(ccx).ptr_to()), opaque_rust_main, llvm::LLVMGetParam(llfn, 0), llvm::LLVMGetParam(llfn, 1), @@ -2406,7 +2370,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, debug!("using user-defined start fn"); let args = { ~[ - C_null(T_opaque_box_ptr(ccx)), + C_null(Type::opaque_box(ccx).ptr_to()), llvm::LLVMGetParam(llfn, 0 as c_uint), llvm::LLVMGetParam(llfn, 1 as c_uint), opaque_crate_map @@ -2432,7 +2396,7 @@ pub fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef, let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]); Store(bcx, llfn, code_cell); let env_cell = GEPi(bcx, pair, [0u, abi::fn_field_box]); - let llenvblobptr = PointerCast(bcx, llenvptr, T_opaque_box_ptr(ccx)); + let llenvblobptr = PointerCast(bcx, llenvptr, Type::opaque_box(ccx).ptr_to()); Store(bcx, llenvblobptr, env_cell); } @@ -2656,215 +2620,98 @@ pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef { } } -pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { - let T_memcpy32_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_ptr(T_i8()), T_i32(), T_i32(), T_i1()]; - let T_memcpy64_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_ptr(T_i8()), T_i64(), T_i32(), T_i1()]; - let T_memset32_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_i8(), T_i32(), T_i32(), T_i1()]; - let T_memset64_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_i8(), T_i64(), T_i32(), T_i1()]; - let T_trap_args: ~[TypeRef] = ~[]; - let T_frameaddress_args: ~[TypeRef] = ~[T_i32()]; - let gcroot = - decl_cdecl_fn(llmod, "llvm.gcroot", - T_fn([T_ptr(T_ptr(T_i8())), T_ptr(T_i8())], - T_void())); - let gcread = - decl_cdecl_fn(llmod, "llvm.gcread", - T_fn([T_ptr(T_i8()), T_ptr(T_ptr(T_i8()))], - T_void())); - let memcpy32 = - decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i32", - T_fn(T_memcpy32_args, T_void())); - let memcpy64 = - decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i64", - T_fn(T_memcpy64_args, T_void())); - let memmove32 = - decl_cdecl_fn(llmod, "llvm.memmove.p0i8.p0i8.i32", - T_fn(T_memcpy32_args, T_void())); - let memmove64 = - decl_cdecl_fn(llmod, "llvm.memmove.p0i8.p0i8.i64", - T_fn(T_memcpy64_args, T_void())); - let memset32 = - decl_cdecl_fn(llmod, "llvm.memset.p0i8.i32", - T_fn(T_memset32_args, T_void())); - let memset64 = - decl_cdecl_fn(llmod, "llvm.memset.p0i8.i64", - T_fn(T_memset64_args, T_void())); - let trap = decl_cdecl_fn(llmod, "llvm.trap", T_fn(T_trap_args, - T_void())); - let frameaddress = decl_cdecl_fn(llmod, "llvm.frameaddress", - T_fn(T_frameaddress_args, - T_ptr(T_i8()))); - let sqrtf32 = decl_cdecl_fn(llmod, "llvm.sqrt.f32", - T_fn([T_f32()], T_f32())); - let sqrtf64 = decl_cdecl_fn(llmod, "llvm.sqrt.f64", - T_fn([T_f64()], T_f64())); - let powif32 = decl_cdecl_fn(llmod, "llvm.powi.f32", - T_fn([T_f32(), T_i32()], T_f32())); - let powif64 = decl_cdecl_fn(llmod, "llvm.powi.f64", - T_fn([T_f64(), T_i32()], T_f64())); - let sinf32 = decl_cdecl_fn(llmod, "llvm.sin.f32", - T_fn([T_f32()], T_f32())); - let sinf64 = decl_cdecl_fn(llmod, "llvm.sin.f64", - T_fn([T_f64()], T_f64())); - let cosf32 = decl_cdecl_fn(llmod, "llvm.cos.f32", - T_fn([T_f32()], T_f32())); - let cosf64 = decl_cdecl_fn(llmod, "llvm.cos.f64", - T_fn([T_f64()], T_f64())); - let powf32 = decl_cdecl_fn(llmod, "llvm.pow.f32", - T_fn([T_f32(), T_f32()], T_f32())); - let powf64 = decl_cdecl_fn(llmod, "llvm.pow.f64", - T_fn([T_f64(), T_f64()], T_f64())); - let expf32 = decl_cdecl_fn(llmod, "llvm.exp.f32", - T_fn([T_f32()], T_f32())); - let expf64 = decl_cdecl_fn(llmod, "llvm.exp.f64", - T_fn([T_f64()], T_f64())); - let exp2f32 = decl_cdecl_fn(llmod, "llvm.exp2.f32", - T_fn([T_f32()], T_f32())); - let exp2f64 = decl_cdecl_fn(llmod, "llvm.exp2.f64", - T_fn([T_f64()], T_f64())); - let logf32 = decl_cdecl_fn(llmod, "llvm.log.f32", - T_fn([T_f32()], T_f32())); - let logf64 = decl_cdecl_fn(llmod, "llvm.log.f64", - T_fn([T_f64()], T_f64())); - let log10f32 = decl_cdecl_fn(llmod, "llvm.log10.f32", - T_fn([T_f32()], T_f32())); - let log10f64 = decl_cdecl_fn(llmod, "llvm.log10.f64", - T_fn([T_f64()], T_f64())); - let log2f32 = decl_cdecl_fn(llmod, "llvm.log2.f32", - T_fn([T_f32()], T_f32())); - let log2f64 = decl_cdecl_fn(llmod, "llvm.log2.f64", - T_fn([T_f64()], T_f64())); - let fmaf32 = decl_cdecl_fn(llmod, "llvm.fma.f32", - T_fn([T_f32(), T_f32(), T_f32()], T_f32())); - let fmaf64 = decl_cdecl_fn(llmod, "llvm.fma.f64", - T_fn([T_f64(), T_f64(), T_f64()], T_f64())); - let fabsf32 = decl_cdecl_fn(llmod, "llvm.fabs.f32", - T_fn([T_f32()], T_f32())); - let fabsf64 = decl_cdecl_fn(llmod, "llvm.fabs.f64", - T_fn([T_f64()], T_f64())); - let floorf32 = decl_cdecl_fn(llmod, "llvm.floor.f32", - T_fn([T_f32()], T_f32())); - let floorf64 = decl_cdecl_fn(llmod, "llvm.floor.f64", - T_fn([T_f64()], T_f64())); - let ceilf32 = decl_cdecl_fn(llmod, "llvm.ceil.f32", - T_fn([T_f32()], T_f32())); - let ceilf64 = decl_cdecl_fn(llmod, "llvm.ceil.f64", - T_fn([T_f64()], T_f64())); - let truncf32 = decl_cdecl_fn(llmod, "llvm.trunc.f32", - T_fn([T_f32()], T_f32())); - let truncf64 = decl_cdecl_fn(llmod, "llvm.trunc.f64", - T_fn([T_f64()], T_f64())); - let ctpop8 = decl_cdecl_fn(llmod, "llvm.ctpop.i8", - T_fn([T_i8()], T_i8())); - let ctpop16 = decl_cdecl_fn(llmod, "llvm.ctpop.i16", - T_fn([T_i16()], T_i16())); - let ctpop32 = decl_cdecl_fn(llmod, "llvm.ctpop.i32", - T_fn([T_i32()], T_i32())); - let ctpop64 = decl_cdecl_fn(llmod, "llvm.ctpop.i64", - T_fn([T_i64()], T_i64())); - let ctlz8 = decl_cdecl_fn(llmod, "llvm.ctlz.i8", - T_fn([T_i8(), T_i1()], T_i8())); - let ctlz16 = decl_cdecl_fn(llmod, "llvm.ctlz.i16", - T_fn([T_i16(), T_i1()], T_i16())); - let ctlz32 = decl_cdecl_fn(llmod, "llvm.ctlz.i32", - T_fn([T_i32(), T_i1()], T_i32())); - let ctlz64 = decl_cdecl_fn(llmod, "llvm.ctlz.i64", - T_fn([T_i64(), T_i1()], T_i64())); - let cttz8 = decl_cdecl_fn(llmod, "llvm.cttz.i8", - T_fn([T_i8(), T_i1()], T_i8())); - let cttz16 = decl_cdecl_fn(llmod, "llvm.cttz.i16", - T_fn([T_i16(), T_i1()], T_i16())); - let cttz32 = decl_cdecl_fn(llmod, "llvm.cttz.i32", - T_fn([T_i32(), T_i1()], T_i32())); - let cttz64 = decl_cdecl_fn(llmod, "llvm.cttz.i64", - T_fn([T_i64(), T_i1()], T_i64())); - let bswap16 = decl_cdecl_fn(llmod, "llvm.bswap.i16", - T_fn([T_i16()], T_i16())); - let bswap32 = decl_cdecl_fn(llmod, "llvm.bswap.i32", - T_fn([T_i32()], T_i32())); - let bswap64 = decl_cdecl_fn(llmod, "llvm.bswap.i64", - T_fn([T_i64()], T_i64())); +macro_rules! ifn ( + ($name:expr, $args:expr, $ret:expr) => ({ + let name = $name; + let f = decl_cdecl_fn(llmod, name, Type::func($args, $ret)); + intrinsics.insert(name, f); + }) +) +pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { + let i8p = Type::i8p(); let mut intrinsics = HashMap::new(); - intrinsics.insert("llvm.gcroot", gcroot); - intrinsics.insert("llvm.gcread", gcread); - intrinsics.insert("llvm.memcpy.p0i8.p0i8.i32", memcpy32); - intrinsics.insert("llvm.memcpy.p0i8.p0i8.i64", memcpy64); - intrinsics.insert("llvm.memmove.p0i8.p0i8.i32", memmove32); - intrinsics.insert("llvm.memmove.p0i8.p0i8.i64", memmove64); - intrinsics.insert("llvm.memset.p0i8.i32", memset32); - intrinsics.insert("llvm.memset.p0i8.i64", memset64); - intrinsics.insert("llvm.trap", trap); - intrinsics.insert("llvm.frameaddress", frameaddress); - intrinsics.insert("llvm.sqrt.f32", sqrtf32); - intrinsics.insert("llvm.sqrt.f64", sqrtf64); - intrinsics.insert("llvm.powi.f32", powif32); - intrinsics.insert("llvm.powi.f64", powif64); - intrinsics.insert("llvm.sin.f32", sinf32); - intrinsics.insert("llvm.sin.f64", sinf64); - intrinsics.insert("llvm.cos.f32", cosf32); - intrinsics.insert("llvm.cos.f64", cosf64); - intrinsics.insert("llvm.pow.f32", powf32); - intrinsics.insert("llvm.pow.f64", powf64); - intrinsics.insert("llvm.exp.f32", expf32); - intrinsics.insert("llvm.exp.f64", expf64); - intrinsics.insert("llvm.exp2.f32", exp2f32); - intrinsics.insert("llvm.exp2.f64", exp2f64); - intrinsics.insert("llvm.log.f32", logf32); - intrinsics.insert("llvm.log.f64", logf64); - intrinsics.insert("llvm.log10.f32", log10f32); - intrinsics.insert("llvm.log10.f64", log10f64); - intrinsics.insert("llvm.log2.f32", log2f32); - intrinsics.insert("llvm.log2.f64", log2f64); - intrinsics.insert("llvm.fma.f32", fmaf32); - intrinsics.insert("llvm.fma.f64", fmaf64); - intrinsics.insert("llvm.fabs.f32", fabsf32); - intrinsics.insert("llvm.fabs.f64", fabsf64); - intrinsics.insert("llvm.floor.f32", floorf32); - intrinsics.insert("llvm.floor.f64", floorf64); - intrinsics.insert("llvm.ceil.f32", ceilf32); - intrinsics.insert("llvm.ceil.f64", ceilf64); - intrinsics.insert("llvm.trunc.f32", truncf32); - intrinsics.insert("llvm.trunc.f64", truncf64); - intrinsics.insert("llvm.ctpop.i8", ctpop8); - intrinsics.insert("llvm.ctpop.i16", ctpop16); - intrinsics.insert("llvm.ctpop.i32", ctpop32); - intrinsics.insert("llvm.ctpop.i64", ctpop64); - intrinsics.insert("llvm.ctlz.i8", ctlz8); - intrinsics.insert("llvm.ctlz.i16", ctlz16); - intrinsics.insert("llvm.ctlz.i32", ctlz32); - intrinsics.insert("llvm.ctlz.i64", ctlz64); - intrinsics.insert("llvm.cttz.i8", cttz8); - intrinsics.insert("llvm.cttz.i16", cttz16); - intrinsics.insert("llvm.cttz.i32", cttz32); - intrinsics.insert("llvm.cttz.i64", cttz64); - intrinsics.insert("llvm.bswap.i16", bswap16); - intrinsics.insert("llvm.bswap.i32", bswap32); - intrinsics.insert("llvm.bswap.i64", bswap64); + + ifn!("llvm.memcpy.p0i8.p0i8.i32", + [i8p, i8p, Type::i32(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memcpy.p0i8.p0i8.i64", + [i8p, i8p, Type::i64(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memmove.p0i8.p0i8.i32", + [i8p, i8p, Type::i32(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memmove.p0i8.p0i8.i64", + [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", + [i8p, Type::i8(), Type::i64(), Type::i32(), Type::i1()], Type::void()); + + ifn!("llvm.trap", [], Type::void()); + ifn!("llvm.frameaddress", [Type::i32()], i8p); + + ifn!("llvm.powi.f32", [Type::f32(), Type::i32()], Type::f32()); + ifn!("llvm.powi.f64", [Type::f64(), Type::i32()], Type::f64()); + ifn!("llvm.pow.f32", [Type::f32(), Type::f32()], Type::f32()); + ifn!("llvm.pow.f64", [Type::f64(), Type::f64()], Type::f64()); + + ifn!("llvm.sqrt.f32", [Type::f32()], Type::f32()); + ifn!("llvm.sqrt.f64", [Type::f64()], Type::f64()); + ifn!("llvm.sin.f32", [Type::f32()], Type::f32()); + ifn!("llvm.sin.f64", [Type::f64()], Type::f64()); + ifn!("llvm.cos.f32", [Type::f32()], Type::f32()); + ifn!("llvm.cos.f64", [Type::f64()], Type::f64()); + ifn!("llvm.exp.f32", [Type::f32()], Type::f32()); + ifn!("llvm.exp.f64", [Type::f64()], Type::f64()); + ifn!("llvm.exp2.f32", [Type::f32()], Type::f32()); + ifn!("llvm.exp2.f64", [Type::f64()], Type::f64()); + ifn!("llvm.log.f32", [Type::f32()], Type::f32()); + ifn!("llvm.log.f64", [Type::f64()], Type::f64()); + ifn!("llvm.log10.f32",[Type::f32()], Type::f32()); + ifn!("llvm.log10.f64",[Type::f64()], Type::f64()); + ifn!("llvm.log2.f32", [Type::f32()], Type::f32()); + ifn!("llvm.log2.f64", [Type::f64()], Type::f64()); + + ifn!("llvm.fma.f32", [Type::f32(), Type::f32(), Type::f32()], Type::f32()); + ifn!("llvm.fma.f64", [Type::f64(), Type::f64(), Type::f64()], Type::f64()); + + ifn!("llvm.fabs.f32", [Type::f32()], Type::f32()); + ifn!("llvm.fabs.f64", [Type::f64()], Type::f64()); + ifn!("llvm.floor.f32",[Type::f32()], Type::f32()); + ifn!("llvm.floor.f64",[Type::f64()], Type::f64()); + ifn!("llvm.ceil.f32", [Type::f32()], Type::f32()); + ifn!("llvm.ceil.f64", [Type::f64()], Type::f64()); + ifn!("llvm.trunc.f32",[Type::f32()], Type::f32()); + ifn!("llvm.trunc.f64",[Type::f64()], Type::f64()); + + ifn!("llvm.ctpop.i8", [Type::i8()], Type::i8()); + ifn!("llvm.ctpop.i16",[Type::i16()], Type::i16()); + ifn!("llvm.ctpop.i32",[Type::i32()], Type::i32()); + ifn!("llvm.ctpop.i64",[Type::i64()], Type::i64()); + + ifn!("llvm.ctlz.i8", [Type::i8() , Type::i1()], Type::i8()); + ifn!("llvm.ctlz.i16", [Type::i16(), Type::i1()], Type::i16()); + ifn!("llvm.ctlz.i32", [Type::i32(), Type::i1()], Type::i32()); + ifn!("llvm.ctlz.i64", [Type::i64(), Type::i1()], Type::i64()); + + ifn!("llvm.cttz.i8", [Type::i8() , Type::i1()], Type::i8()); + ifn!("llvm.cttz.i16", [Type::i16(), Type::i1()], Type::i16()); + ifn!("llvm.cttz.i32", [Type::i32(), Type::i1()], Type::i32()); + ifn!("llvm.cttz.i64", [Type::i64(), Type::i1()], Type::i64()); + + ifn!("llvm.bswap.i16",[Type::i16()], Type::i16()); + ifn!("llvm.bswap.i32",[Type::i32()], Type::i32()); + ifn!("llvm.bswap.i64",[Type::i64()], Type::i64()); return intrinsics; } -pub fn declare_dbg_intrinsics(llmod: ModuleRef, - intrinsics: &mut HashMap<&'static str, ValueRef>) { - let declare = - decl_cdecl_fn(llmod, "llvm.dbg.declare", - T_fn([T_metadata(), T_metadata()], T_void())); - let value = - decl_cdecl_fn(llmod, "llvm.dbg.value", - T_fn([T_metadata(), T_i64(), T_metadata()], T_void())); - intrinsics.insert("llvm.dbg.declare", declare); - intrinsics.insert("llvm.dbg.value", value); +pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'static str, ValueRef>) { + ifn!("llvm.dbg.declare", [Type::metadata(), Type::metadata()], Type::void()); + ifn!("llvm.dbg.value", [Type::metadata(), Type::i64(), Type::metadata()], Type::void()); } pub fn trap(bcx: block) { - let v: ~[ValueRef] = ~[]; - match bcx.ccx().intrinsics.find(& &"llvm.trap") { - Some(&x) => { Call(bcx, x, v); }, + match bcx.ccx().intrinsics.find_equiv("llvm.trap") { + Some(&x) => { Call(bcx, x, []); }, _ => bcx.sess().bug("unbound llvm.trap in trap") } } @@ -2877,7 +2724,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, T_i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32(), buf) } }; unsafe { @@ -2888,8 +2735,8 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { } pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { - let elttype = T_struct([ccx.int_type, ccx.int_type], false); - let maptype = T_array(elttype, ccx.module_data.len() + 1); + 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| { unsafe { llvm::LLVMAddGlobal(ccx.llmod, maptype, buf) @@ -2926,7 +2773,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, llmod: ModuleRef) -> ValueRef { let targ_cfg = sess.targ_cfg; - let int_type = T_int(targ_cfg); + let int_type = Type::int(targ_cfg.arch); let mut n_subcrates = 1; let cstore = sess.cstore; while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; } @@ -2936,8 +2783,8 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, ~"toplevel" }; let sym_name = ~"_rust_crate_map_" + mapname; - let arrtype = T_array(int_type, n_subcrates as uint); - let maptype = T_struct([T_i32(), T_ptr(T_i8()), int_type, arrtype], false); + 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) @@ -2984,7 +2831,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) { llvm::LLVMSetInitializer(map, C_struct( [C_i32(1), lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, - T_ptr(T_i8())), + Type::i8p()), p2i(ccx, mod_map), C_array(ccx.int_type, subcrates)])); } @@ -3032,11 +2879,11 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { }); lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); - let t_ptr_i8 = T_ptr(T_i8()); + let t_ptr_i8 = Type::i8p(); llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8); - let llvm_used = str::as_c_str("llvm.used", |buf| { - llvm::LLVMAddGlobal(cx.llmod, T_array(t_ptr_i8, 1u), buf) - }); + let llvm_used = do "llvm.used".as_c_str |buf| { + llvm::LLVMAddGlobal(cx.llmod, Type::array(t_ptr_i8, 1u), buf) + }; lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage); llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, [llglobal])); } diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index f6c9c15f19bd7..be14da66a1624 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -13,7 +13,7 @@ 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, TypeRef, BasicBlockRef, BuilderRef, ModuleRef}; +use lib::llvm::{ValueRef, Type, BasicBlockRef, BuilderRef, ModuleRef}; use lib; use middle::trans::common::*; use middle::trans::machine::llalign_of_min; @@ -186,7 +186,7 @@ pub fn Invoke(cx: block, Catch: BasicBlockRef) -> ValueRef { if cx.unreachable { - return C_null(T_i8()); + return C_null(Type::i8()); } check_not_terminated(cx); terminate(cx, "Invoke"); @@ -486,35 +486,35 @@ pub fn Not(cx: block, V: ValueRef) -> ValueRef { } /* Memory */ -pub fn Malloc(cx: block, Ty: TypeRef) -> ValueRef { +pub fn Malloc(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "malloc"); - return llvm::LLVMBuildMalloc(B(cx), Ty, noname()); + return llvm::LLVMBuildMalloc(B(cx), Ty.to_ref(), noname()); } } -pub fn ArrayMalloc(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef { +pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "arraymalloc"); - return llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname()); + return llvm::LLVMBuildArrayMalloc(B(cx), Ty.to_ref(), Val, noname()); } } -pub fn Alloca(cx: block, Ty: TypeRef) -> ValueRef { +pub fn Alloca(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); } count_insn(cx, "alloca"); - return llvm::LLVMBuildAlloca(B(cx), Ty, noname()); + return llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname()); } } -pub fn ArrayAlloca(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef { +pub fn ArrayAlloca(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); } count_insn(cx, "arrayalloca"); - return llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname()); + return llvm::LLVMBuildArrayAlloca(B(cx), Ty.to_ref(), Val, noname()); } } @@ -597,7 +597,7 @@ pub fn AtomicStore(cx: block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrderin pub fn GEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "gep"); return llvm::LLVMBuildGEP(B(cx), Pointer, vec::raw::to_ptr(Indices), Indices.len() as c_uint, noname()); @@ -617,7 +617,7 @@ pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef { pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "inboundsgep"); return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, vec::raw::to_ptr(Indices), @@ -628,7 +628,7 @@ pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "structgep"); return llvm::LLVMBuildStructGEP(B(cx), Pointer, @@ -639,7 +639,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(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p()); } count_insn(cx, "globalstring"); return llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); } @@ -647,163 +647,163 @@ 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(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p()); } count_insn(cx, "globalstringptr"); return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); } } /* Casts */ -pub fn Trunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn Trunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "trunc"); - return llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildTrunc(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn ZExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn ZExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "zext"); - return llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildZExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sext"); - return llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPToUI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPToUI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptoui"); - return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPToSI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPToSI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptosi"); - return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy.to_ref(),noname()); } } -pub fn UIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn UIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "uitofp"); - return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sitofp"); - return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPTrunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPTrunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptrunc"); - return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fpext"); - return llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn PtrToInt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn PtrToInt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "ptrtoint"); - return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn IntToPtr(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn IntToPtr(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "inttoptr"); - return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn BitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn BitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "bitcast"); - return llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "zextorbitcast"); - return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sextorbitcast"); - return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "truncorbitcast"); - return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef, _: *u8) +pub fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: Type, _: *u8) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } count_insn(cx, "cast"); - return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname()); + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } + return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy.to_ref(), noname()); } } -pub fn PointerCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn PointerCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "pointercast"); - return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn IntCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn IntCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "intcast"); - return llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildIntCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fpcast"); - return llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPCast(B(cx), Val, DestTy.to_ref(), noname()); } } @@ -812,7 +812,7 @@ pub fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { pub fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "icmp"); return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname()); } @@ -821,27 +821,27 @@ pub fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef) pub fn FCmp(cx: block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "fcmp"); return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname()); } } /* Miscellaneous instructions */ -pub fn EmptyPhi(cx: block, Ty: TypeRef) -> ValueRef { +pub fn EmptyPhi(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } count_insn(cx, "emptyphi"); - return llvm::LLVMBuildPhi(B(cx), Ty, noname()); + return llvm::LLVMBuildPhi(B(cx), Ty.to_ref(), noname()); } } -pub fn Phi(cx: block, Ty: TypeRef, vals: &[ValueRef], bbs: &[BasicBlockRef]) +pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } assert_eq!(vals.len(), bbs.len()); - let phi = EmptyPhi(cx, Ty); + let phi = EmptyPhi(cx, Ty.to_ref()); count_insn(cx, "addincoming"); llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals), vec::raw::to_ptr(bbs), @@ -886,12 +886,9 @@ pub fn add_comment(bcx: block, text: &str) { let sanitized = text.replace("$", ""); let comment_text = ~"# " + sanitized.replace("\n", "\n\t# "); + count_insn(bcx, "inlineasm"); let asm = str::as_c_str(comment_text, |c| { - str::as_c_str("", |e| { - count_insn(bcx, "inlineasm"); - llvm::LLVMConstInlineAsm(T_fn([], T_void()), c, e, - False, False) - }) + llvm::LLVMConstInlineAsm(Type::func([], Type::void()), c, noname(), False, False) }); Call(bcx, asm, []); } @@ -899,7 +896,7 @@ pub fn add_comment(bcx: block, text: &str) { } pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, - inputs: &[ValueRef], output: TypeRef, + inputs: &[ValueRef], output: Type, volatile: bool, alignstack: bool, dia: AsmDialect) -> ValueRef { unsafe { @@ -916,9 +913,8 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, }; debug!("Asm Output Type: %?", cx.ccx().tn.type_to_str(output)); - let llfty = T_fn(argtys, output); - let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile, - alignstack, dia as c_uint); + let fty = Type::func(argtys, output); + let v = llvm::LLVMInlineAsm(llfty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); Call(cx, v, inputs) } @@ -971,18 +967,18 @@ pub fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) -> } } -pub fn VAArg(cx: block, list: ValueRef, Ty: TypeRef) -> ValueRef { +pub fn VAArg(cx: block, list: ValueRef, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } count_insn(cx, "vaarg"); - return llvm::LLVMBuildVAArg(B(cx), list, Ty, noname()); + return llvm::LLVMBuildVAArg(B(cx), list, Ty.to_ref(), noname()); } } pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "extractelement"); return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname()); } @@ -991,7 +987,7 @@ pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef, Index: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "insertelement"); llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname()) } @@ -1000,7 +996,7 @@ pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef, pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, Mask: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "shufflevector"); llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()) } @@ -1008,15 +1004,16 @@ pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef { unsafe { - let Undef = llvm::LLVMGetUndef(T_vector(val_ty(EltVal), NumElts)); + let elt_ty = val_ty(EltVal); + let Undef = llvm::LLVMGetUndef(Type::vector(elt_ty, NumElts).to_ref()); let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0)); - ShuffleVector(cx, VecVal, Undef, C_null(T_vector(T_i32(), NumElts))) + ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(Type::i32().to_ref(), NumElts))) } } pub fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "extractvalue"); return llvm::LLVMBuildExtractValue( B(cx), AggVal, Index as c_uint, noname()); @@ -1035,7 +1032,7 @@ pub fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef, pub fn IsNull(cx: block, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "isnull"); return llvm::LLVMBuildIsNull(B(cx), Val, noname()); } @@ -1043,7 +1040,7 @@ pub fn IsNull(cx: block, Val: ValueRef) -> ValueRef { pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "isnotnull"); return llvm::LLVMBuildIsNotNull(B(cx), Val, noname()); } @@ -1076,13 +1073,13 @@ pub fn Trap(cx: block) { } } -pub fn LandingPad(cx: block, Ty: TypeRef, PersFn: ValueRef, +pub fn LandingPad(cx: block, Ty: Type, PersFn: ValueRef, NumClauses: uint) -> ValueRef { unsafe { check_not_terminated(cx); assert!(!cx.unreachable); count_insn(cx, "landingpad"); - return llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, + return llvm::LLVMBuildLandingPad(B(cx), Ty.to_ref(), PersFn, NumClauses as c_uint, noname()); } } diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index ced19ce57ad5f..036f34b1974ec 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -26,7 +26,7 @@ pub trait ABIInfo { pub struct LLVMType { cast: bool, - ty: TypeRef + ty: Type } pub struct FnType { @@ -37,10 +37,10 @@ pub struct FnType { } impl FnType { - pub fn decl_fn(&self, decl: &fn(fnty: TypeRef) -> ValueRef) -> ValueRef { + 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 = T_fn(atys, rty); + let fnty = Type::func(atys, rty); let llfn = decl(fnty); for self.attrs.iter().enumerate().advance |(i, a)| { @@ -59,7 +59,7 @@ impl FnType { pub fn build_shim_args(&self, bcx: block, - arg_tys: &[TypeRef], + arg_tys: &[Type], llargbundle: ValueRef) -> ~[ValueRef] { let mut atys: &[LLVMType] = self.arg_tys; @@ -96,7 +96,7 @@ impl FnType { pub fn build_shim_ret(&self, bcx: block, - arg_tys: &[TypeRef], + arg_tys: &[Type], ret_def: bool, llargbundle: ValueRef, llretval: ValueRef) { @@ -132,7 +132,7 @@ impl FnType { pub fn build_wrap_args(&self, bcx: block, - ret_ty: TypeRef, + ret_ty: Type, llwrapfn: ValueRef, llargbundle: ValueRef) { let mut atys: &[LLVMType] = self.arg_tys; @@ -145,7 +145,7 @@ impl FnType { get_param(llwrapfn, 0u) } else if self.ret_ty.cast { let retptr = alloca(bcx, self.ret_ty.ty); - BitCast(bcx, retptr, T_ptr(ret_ty)) + BitCast(bcx, retptr, ret_ty.ptr_to()) } else { alloca(bcx, ret_ty) }; @@ -182,14 +182,14 @@ impl FnType { if bcx.fcx.llretptr.is_some() { let llretval = load_inbounds(bcx, llargbundle, [ 0, arg_tys.len() ]); let llretval = if self.ret_ty.cast { - let retptr = BitCast(bcx, llretval, T_ptr(self.ret_ty.ty)); + let retptr = BitCast(bcx, llretval, self.ret_ty.ty.ptr_to()); Load(bcx, retptr) } else { Load(bcx, llretval) }; let llretptr = BitCast(bcx, bcx.fcx.llretptr.get(), - T_ptr(self.ret_ty.ty)); + self.ret_ty.ty.ptr_to()); Store(bcx, llretval, llretptr); } } diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 9ad66c066715e..f29ccad76b178 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -10,12 +10,9 @@ use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; use lib::llvm::struct_tys; -use lib::llvm::TypeRef; use lib::llvm::{Attribute, StructRetAttribute}; use lib::llvm::True; use middle::trans::cabi::{ABIInfo, FnType, LLVMType}; -use middle::trans::common::{T_i8, T_i16, T_i32, T_i64}; -use middle::trans::common::{T_array, T_ptr, T_void}; use core::option::{Option, None, Some}; use core::uint; @@ -24,102 +21,102 @@ fn align_up_to(off: uint, a: uint) -> uint { return (off + a - 1u) / a * a; } -fn align(off: uint, ty: TypeRef) -> uint { +fn align(off: uint, ty: Type) -> uint { let a = ty_align(ty); return align_up_to(off, a); } -fn ty_align(ty: TypeRef) -> uint { +fn ty_align(ty: Type) -> uint { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + match ty.kind() { Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } Pointer => 4, Float => 4, Double => 8, Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { + if ty.is_packed() { 1 } else { - let str_tys = struct_tys(ty); + let str_tys = ty.field_types(); str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) } } Array => { - let elt = llvm::LLVMGetElementType(ty); + let elt = ty.element_type(); ty_align(elt) } _ => fail!("ty_align: unhandled type") - }; + } } } -fn ty_size(ty: TypeRef) -> uint { +fn ty_size(ty: Type) -> uint { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + match ty.kind() { Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + ((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); + 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 = struct_tys(ty); + 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 = llvm::LLVMGetArrayLength(ty) as uint; - let elt = llvm::LLVMGetElementType(ty); + let len = ty.array_length(); + let elt = ty.element_type(); let eltsz = ty_size(elt); len * eltsz } _ => fail!("ty_size: unhandled type") - }; + } } } -fn classify_ret_ty(ty: TypeRef) -> (LLVMType, Option) { +fn classify_ret_ty(ty: Type) -> (LLVMType, Option) { if is_reg_ty(ty) { return (LLVMType { cast: false, ty: ty }, None); } let size = ty_size(ty); if size <= 4 { let llty = if size <= 1 { - T_i8() + Type::i8() } else if size <= 2 { - T_i16() + Type::i16() } else { - T_i32() + Type::i32() }; return (LLVMType { cast: true, ty: llty }, None); } - (LLVMType { cast: false, ty: T_ptr(ty) }, Some(StructRetAttribute)) + (LLVMType { cast: false, ty: ty.ptr_to() }, Some(StructRetAttribute)) } -fn classify_arg_ty(ty: TypeRef) -> (LLVMType, Option) { +fn classify_arg_ty(ty: Type) -> (LLVMType, Option) { if is_reg_ty(ty) { return (LLVMType { cast: false, ty: ty }, None); } let align = ty_align(ty); let size = ty_size(ty); let llty = if align <= 4 { - T_array(T_i32(), (size + 3) / 4) + Type::array(Type::i32(), (size + 3) / 4) } else { - T_array(T_i64(), (size + 7) / 8) + Type::array(Type::i64(), (size + 7) / 8) }; (LLVMType { cast: true, ty: llty }, None) } -fn is_reg_ty(ty: TypeRef) -> bool { +fn is_reg_ty(ty: Type) -> bool { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + match ty.kind() { Integer | Pointer | Float @@ -133,8 +130,8 @@ enum ARM_ABIInfo { ARM_ABIInfo } impl ABIInfo for ARM_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { let mut arg_tys = ~[]; let mut attrs = ~[]; @@ -147,14 +144,14 @@ impl ABIInfo for ARM_ABIInfo { let mut (ret_ty, ret_attr) = if ret_def { classify_ret_ty(rty) } else { - (LLVMType { cast: false, ty: T_void() }, None) + (LLVMType { cast: false, ty: Type::void() }, None) }; let sret = ret_attr.is_some(); if sret { arg_tys.unshift(ret_ty); attrs.unshift(ret_attr); - ret_ty = LLVMType { cast: false, ty: T_void() }; + ret_ty = LLVMType { cast: false, ty: Type::void() }; } return FnType { diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 0c771d21da5ce..de988493b471f 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -14,9 +14,9 @@ use core::libc::c_uint; use core::ptr; use core::uint; use core::vec; -use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double}; -use lib::llvm::{Struct, Array, Attribute}; -use lib::llvm::{StructRetAttribute}; +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::*; @@ -26,23 +26,11 @@ fn align_up_to(off: uint, a: uint) -> uint { return (off + a - 1u) / a * a; } -fn align(off: uint, ty: TypeRef) -> uint { +fn align(off: uint, ty: Type) -> uint { let a = ty_align(ty); return align_up_to(off, a); } -fn struct_tys(ty: TypeRef) -> ~[TypeRef] { - unsafe { - let n = llvm::LLVMCountStructElementTypes(ty); - if (n == 0) { - return ~[]; - } - let mut elts = vec::from_elem(n as uint, ptr::null()); - llvm::LLVMGetStructElementTypes(ty, &mut elts[0]); - return elts; - } -} - fn ty_align(ty: TypeRef) -> uint { unsafe { return match llvm::LLVMGetTypeKind(ty) { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index b8bf295e809ae..a72f9489abcc9 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -690,8 +690,8 @@ impl block_ { self.ccx().tn.val_to_str(val) } - pub fn llty_str(&self, llty: TypeRef) -> ~str { - self.ccx().tn.type_to_str(llty) + pub fn llty_str(&self, ty: Type) -> ~str { + self.ccx().tn.type_to_str(ty) } pub fn ty_to_str(&self, t: ty::t) -> ~str { @@ -708,6 +708,7 @@ impl block_ { } } +/* // LLVM type constructors. pub fn T_void() -> TypeRef { unsafe { return llvm::LLVMVoidTypeInContext(base::task_llcx()); } @@ -931,19 +932,6 @@ pub fn T_opaque_vec(targ_cfg: @session::config) -> TypeRef { return T_vec2(targ_cfg, 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). -pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { - let ptr = ty::mk_ptr( - tcx, - ty::mt {ty: ty::mk_nil(), mutbl: ast::m_imm} - ); - return ty::mk_tup(tcx, ~[ty::mk_uint(), ty::mk_type(tcx), - ptr, ptr, - t]); -} - 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]; @@ -1025,6 +1013,20 @@ pub fn T_opaque_trait(cx: &CrateContext, store: ty::TraitStore) -> TypeRef { 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). +pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { + let ptr = ty::mk_ptr( + tcx, + ty::mt {ty: ty::mk_nil(), mutbl: ast::m_imm} + ); + return ty::mk_tup(tcx, ~[ty::mk_uint(), ty::mk_type(tcx), + ptr, ptr, + t]); +} // LLVM constant constructors. diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index ed5c2aa2e0b90..ada0284e0e317 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -37,8 +37,7 @@ 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,T_int,T_float,T_tydesc,T_opaque_vec}; -use middle::trans::common::{new_namegen,new_addrspace_gen}; +use middle::trans::common::{mono_id,new_namegen,new_addrspace_gen}; use middle::trans::base::{decl_crate_map}; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 65f86c30ea301..851ff4511a039 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -10,15 +10,19 @@ use core::prelude::*; -use lib::llvm::{llvm, TypeRef, Bool, False, True}; +use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind}; + +use middle::ty; use middle::trans::context::CrateContext; use middle::trans::base; -use syntax::{ast,abi}; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use syntax::ast; +use syntax::abi::{Architecture, X86, X86_64, Arm, Mips}; +use back::abi; use core::vec; +use core::cast; use core::libc::{c_uint}; @@ -27,9 +31,7 @@ pub struct Type { } macro_rules! ty ( - ($e:expr) => ( Type::from_ref(unsafe { - - })) + ($e:expr) => ( Type::from_ref(unsafe { $e })) ) /** @@ -94,14 +96,18 @@ impl Type { Type::i32() } - pub fn int(arch: abi::Architecture) -> Type { + pub fn i8p() -> Type { + Type::i8().ptr_to() + } + + pub fn int(arch: Architecture) -> Type { match arch { X86 | Arm | Mips => Type::i32(), X86_64 => Type::i64() } } - pub fn float(_: abi::Architecture) -> Type { + pub fn float(_: Architecture) -> Type { // All architectures currently just use doubles as the default // float size Type::f64() @@ -136,7 +142,7 @@ impl Type { } } - pub fn size_t(arch: abi::Architecture) -> Type { + pub fn size_t(arch: Architecture) -> Type { Type::int(arch) } @@ -147,8 +153,6 @@ impl Type { } pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> Type { - assert!(fn_ty.is_func(), "`fn_ty` must be a function type"); - Type::struct_([fn_ty.ptr_to(), Type::opaque_cbox_ptr(cx)], false) } @@ -186,7 +190,7 @@ impl Type { return ty; } - pub fn tydesc(arch: abi::Architecture) -> 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(); @@ -197,7 +201,7 @@ impl Type { let int_ty = Type::int(arch); let elems = [ - int_type, int_type, + int_ty, int_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, pvoid, pvoid ]; @@ -207,21 +211,21 @@ impl Type { return tydesc; } - pub fn array(ty: &Type, len: uint) -> Type { + pub fn array(ty: &Type, len: u64) -> Type { ty!(llvm::LLVMArrayType(ty.to_ref(), len as c_uint)) } - pub fn vector(ty: &Type, len: uint) -> Type { + pub fn vector(ty: &Type, len: u64) -> Type { ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint)) } - pub fn vec(arch: abi::Architecture, ty: &Type) -> Type { + pub fn vec(arch: Architecture, ty: &Type) -> Type { Type::struct_( [ Type::int(arch), Type::int(arch), Type::array(ty, 0) ], false) } - pub fn opaque_vec(arch: abi::Architecture) -> Type { + pub fn opaque_vec(arch: Architecture) -> Type { Type::vec(arch, Type::i8()) } @@ -238,7 +242,7 @@ impl Type { } pub fn box(ctx: &CrateContext, ty: &Type) -> Type { - Type::struct_(Type::box_header_fields(ctx) + [t], false) + Type::struct_(Type::box_header_fields(ctx) + [ty], false) } pub fn opaque_box(ctx: &CrateContext) -> Type { @@ -257,13 +261,88 @@ impl Type { cx.int_type } - pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { - assert!(self.is_struct(), "Type must be a struct"); + pub fn captured_tydescs(ctx: &CrateContext, num: uint) -> Type { + Type::struct_(vec::from_elem(num, ctx.tydesc_type.ptr_to()), false) + } + + pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type { + let tydesc_ptr = ctx.tydesc_type.ptr_to(); + match store { + ty::BoxTraitStore => { + Type::struct_( + [ tydesc_ptr, Type::opaque_box(ctx).ptr_to() ], + false) + } + ty::UniqTraitStore => { + Type::struct_( + [ tydesc_ptr, Type::unique(ctx, Type::i8()).ptr_to()], + false) + } + ty::RegionTraitStore(*) => { + Type::struct_( + [ tydesc_ptr, Type::i8().ptr_to() ], + false) + } + } + } + pub fn kind(&self) -> TypeKind { + unsafe { + llvm::LLVMGetTypeKind(self.to_ref()) + } + } + + pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { unsafe { let vec : &[TypeRef] = cast::transmute(els); - llvm::LLVMStructSetBody(self.to_ref(), to_ptr(vec), + llvm::LLVMStructSetBody(self.to_ref(), vec::raw::to_ptr(vec), els.len() as c_uint, packed as Bool) } } + + pub fn ptr_to(&self) -> Type { + ty!(llvm::LLVMPointerType(self.to_ref())) + } + + pub fn get_field(&self, idx: uint) -> Type { + unsafe { + let num_fields = llvm::LLVMCountStructElementTypes(self.to_ref()) as uint; + let mut elems = vec::from_elem(num_fields, 0 as TypeRef); + + llvm::LLVMGetStructElementTypes(self.to_ref(), vec::raw::to_mut_ptr(elems)); + + Type::from_ref(elems[idx]) + } + } + + pub fn is_packed(&self) -> bool { + unsafe { + llvm::LLVMIsPackedStruct(self.to_ref()) == True + } + } + + pub fn element_type(&self) -> Type { + unsafe { + Type::from_ref(llvm::LLVMGetElementType(self.to_ref())) + } + } + + pub fn array_length(&self) -> uint { + unsafe { + llvm::LLVMGetArrayLength(self.to_ref()) as uint + } + } + + pub fn field_types(&self) -> ~[Type] { + unsafe { + let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) 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]); + cast::transmute(elts) + } + } + }