use middle::trans::type_of::*;
use middle::trans::value::Value;
use middle::ty;
-use middle::typeck;
use util::common::indenter;
use util::ppaux::{Repr, ty_to_string};
use util::sha2::Sha256;
match ty::get(output).sty {
// functions returning bottom may unwind, but can never return normally
ty::ty_bot => {
- unsafe {
- llvm::LLVMAddFunctionAttribute(llfn,
- llvm::FunctionIndex as c_uint,
- llvm::NoReturnAttribute as uint64_t)
- }
+ llvm::SetFunctionAttribute(llfn, llvm::NoReturnAttribute)
}
_ => {}
}
if ccx.tcx().sess.opts.cg.no_redzone {
- unsafe {
- llvm::LLVMAddFunctionAttribute(llfn,
- llvm::FunctionIndex as c_uint,
- llvm::NoRedZoneAttribute as uint64_t)
- }
+ llvm::SetFunctionAttribute(llfn, llvm::NoRedZoneAttribute)
}
llvm::SetFunctionCallConv(llfn, cc);
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
}
-pub fn malloc_raw_dyn_proc<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
- t: ty::t, alloc_fn: LangItem)
- -> Result<'blk, 'tcx> {
+pub fn malloc_raw_dyn_proc<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: ty::t) -> Result<'blk, 'tcx> {
let _icx = push_ctxt("malloc_raw_dyn_proc");
let ccx = bcx.ccx();
- let langcall = require_alloc_fn(bcx, t, alloc_fn);
-
// Grab the TypeRef type of ptr_ty.
let ptr_ty = ty::mk_uniq(bcx.tcx(), t);
let ptr_llty = type_of(ccx, ptr_ty);
let size = llsize_of(bcx.ccx(), llty);
let llalign = C_uint(ccx, llalign_of_min(bcx.ccx(), llty) as uint);
- // Allocate space:
- let drop_glue = glue::get_drop_glue(ccx, ty::mk_uniq(bcx.tcx(), t));
- let r = callee::trans_lang_call(
- bcx,
- langcall,
- [
- PointerCast(bcx, drop_glue, Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to()),
- size,
- llalign
- ],
- None);
- Result::new(r.bcx, PointerCast(r.bcx, r.val, ptr_llty))
+ // Allocate space and store the destructor pointer:
+ let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, ptr_llty, t, size, llalign);
+ let dtor_ptr = GEPi(bcx, llbox, [0u, abi::box_field_drop_glue]);
+ let drop_glue_field_ty = type_of(ccx, ty::mk_nil_ptr(bcx.tcx()));
+ let drop_glue = PointerCast(bcx, glue::get_drop_glue(ccx, ty::mk_uniq(bcx.tcx(), t)),
+ drop_glue_field_ty);
+ Store(bcx, drop_glue, dtor_ptr);
+
+ Result::new(bcx, llbox)
}
// Since we're in trans we don't care for any region parameters
let ref substs = subst::Substs::erased(substs.types.clone());
- let vtables = typeck::check::vtable::trans_resolve_method(ccx.tcx(), did.node, substs);
- let (val, _) = monomorphize::monomorphic_fn(ccx, did, substs, vtables, None);
+ let (val, _) = monomorphize::monomorphic_fn(ccx, did, substs, None);
val
} else if did.krate == ast::LOCAL_CRATE {
match tcx.map.find(id) {
Some(ast_map::NodeItem(i)) => {
match i.node {
- ast::ItemFn(_, _, _, _, blk) => {
+ ast::ItemFn(_, _, _, _, ref blk) => {
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_item(&mut explicit, &*i);
}
Some(ast_map::NodeTraitItem(trait_method)) => {
match *trait_method {
- ast::ProvidedMethod(m) => {
+ ast::ProvidedMethod(ref m) => {
match m.node {
- ast::MethDecl(_, _, _, _, _, _, blk, _) => {
+ ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
- visit::walk_method_helper(&mut explicit, &*m);
+ visit::walk_method_helper(&mut explicit, &**m);
visit::walk_expr_opt(&mut implicit, &blk.expr);
explicit.found || implicit.found
}
tcx.sess.bug("unexpected variant: required trait method \
in has_nested_returns")
}
+ ast::TypeTraitItem(_) => {
+ tcx.sess.bug("unexpected variant: type trait item in \
+ has_nested_returns")
+ }
}
}
- Some(ast_map::NodeImplItem(ref ii)) => {
- match **ii {
+ Some(ast_map::NodeImplItem(ii)) => {
+ match *ii {
ast::MethodImplItem(ref m) => {
match m.node {
- ast::MethDecl(_, _, _, _, _, _, blk, _) => {
+ ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_method_helper(&mut explicit, &**m);
ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
}
}
+ ast::TypeImplItem(_) => {
+ tcx.sess.bug("unexpected variant: type impl item in \
+ has_nested_returns")
+ }
}
}
Some(ast_map::NodeExpr(e)) => {
match e.node {
- ast::ExprFnBlock(_, _, blk) |
- ast::ExprProc(_, blk) |
- ast::ExprUnboxedFn(_, _, _, blk) => {
+ ast::ExprFnBlock(_, _, ref blk) |
+ ast::ExprProc(_, ref blk) |
+ ast::ExprUnboxedFn(_, _, _, ref blk) => {
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
- visit::walk_expr(&mut explicit, &*e);
+ visit::walk_expr(&mut explicit, e);
visit::walk_expr_opt(&mut implicit, &blk.expr);
explicit.found || implicit.found
}
needs_ret_allocas: nested_returns,
personality: Cell::new(None),
caller_expects_out_pointer: uses_outptr,
- llargs: RefCell::new(NodeMap::new()),
lllocals: RefCell::new(NodeMap::new()),
llupvars: RefCell::new(NodeMap::new()),
id: id,
let arg_scope_id = cleanup::CustomScope(arg_scope);
- for (i, arg_datum) in arg_datums.move_iter().enumerate() {
+ for (i, arg_datum) in arg_datums.into_iter().enumerate() {
// For certain mode/type combinations, the raw llarg values are passed
// by value. However, within the fn body itself, we want to always
// have all locals and arguments be by-ref so that we can cancel the
// This alloca should be optimized away by LLVM's mem-to-reg pass in
// the event it's not truly needed.
- bcx = _match::store_arg(bcx, args[i].pat, arg_datum, arg_scope_id);
+ bcx = _match::store_arg(bcx, &*args[i].pat, arg_datum, arg_scope_id);
if fcx.ccx.sess().opts.debuginfo == FullDebugInfo {
debuginfo::create_argument_metadata(bcx, &args[i]);
assert_eq!(arg_datums.len(), 1);
- let arg_datum = arg_datums.move_iter().next().unwrap();
+ let arg_datum = arg_datums.into_iter().next().unwrap();
// Untuple the rest of the arguments.
let tuple_datum =
tuple_element_datum.to_rvalue_datum(bcx,
"arg"));
bcx = _match::store_arg(bcx,
- args[j].pat,
+ &*args[j].pat,
tuple_element_datum,
arg_scope_id);
if !type_is_zero_size(ccx, result_ty) {
match args {
callee::ArgExprs(exprs) => {
- let fields = exprs.iter().map(|x| *x).enumerate().collect::<Vec<_>>();
+ let fields = exprs.iter().map(|x| &**x).enumerate().collect::<Vec<_>>();
bcx = expr::trans_adt(bcx, result_ty, disr, fields.as_slice(),
None, expr::SaveIn(llresult));
}
if !type_is_zero_size(fcx.ccx, result_ty) {
let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
let repr = adt::represent_type(ccx, result_ty);
- for (i, arg_datum) in arg_datums.move_iter().enumerate() {
+ for (i, arg_datum) in arg_datums.into_iter().enumerate() {
let lldestptr = adt::trans_field_ptr(bcx,
&*repr,
dest,
ast_map::NodeTraitItem(trait_method) => {
debug!("get_item_val(): processing a NodeTraitItem");
match *trait_method {
- ast::RequiredMethod(_) => {
- ccx.sess().bug("unexpected variant: required trait method in \
- get_item_val()");
+ ast::RequiredMethod(_) | ast::TypeTraitItem(_) => {
+ ccx.sess().bug("unexpected variant: required trait \
+ method in get_item_val()");
}
- ast::ProvidedMethod(m) => {
- register_method(ccx, id, &*m)
+ ast::ProvidedMethod(ref m) => {
+ register_method(ccx, id, &**m)
}
}
}
ast_map::NodeImplItem(ii) => {
match *ii {
- ast::MethodImplItem(m) => register_method(ccx, id, &*m),
+ ast::MethodImplItem(ref m) => register_method(ccx, id, &**m),
+ ast::TypeImplItem(ref typedef) => {
+ ccx.sess().span_bug(typedef.span,
+ "unexpected variant: required impl \
+ method in get_item_val()")
+ }
}
}
}
}
-pub fn trans_crate(krate: ast::Crate,
- analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
+pub fn trans_crate<'tcx>(analysis: CrateAnalysis<'tcx>)
+ -> (ty::ctxt<'tcx>, CrateTranslation) {
let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
+ let krate = tcx.map.krate();
// Before we touch LLVM, make sure that multithreading is enabled.
unsafe {
}
}
- let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
+ let link_meta = link::build_link_meta(&tcx.sess, krate, name);
let codegen_units = tcx.sess.opts.cg.codegen_units;
let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(),
}
// Translate the metadata.
- let metadata = write_metadata(&shared_ccx, &krate);
+ let metadata = write_metadata(&shared_ccx, krate);
if shared_ccx.sess().trans_stats() {
let stats = shared_ccx.stats();
// the final product, so LTO needs to preserve them.
shared_ccx.sess().cstore.iter_crate_data(|cnum, _| {
let syms = csearch::get_reachable_extern_fns(&shared_ccx.sess().cstore, cnum);
- reachable.extend(syms.move_iter().map(|did| {
+ reachable.extend(syms.into_iter().map(|did| {
csearch::get_symbol(&shared_ccx.sess().cstore, did)
}));
});