pub fn init_function<'a, 'tcx>(fcx: &'a FunctionContext<'a, 'tcx>,
                               skip_retptr: bool,
                               output: ty::FnOutput<'tcx>)
                               -> Block<'a, 'tcx> {
    let entry_bcx = fcx.new_temp_block("entry-block");

    // Use a dummy instruction as the insertion point for all allocas.
    // This is later removed in FunctionContext::cleanup.
    fcx.alloca_insert_pt.set(Some(unsafe {
        Load(entry_bcx, C_null(Type::i8p(fcx.ccx)));
        llvm::LLVMGetFirstInstruction(entry_bcx.llbb)
    }));

    if let ty::FnConverging(output_type) = output {
        // This shouldn't need to recompute the return type,
        // as new_fn_ctxt did it already.
        let substd_output_type = fcx.monomorphize(&output_type);
        if !return_type_is_void(fcx.ccx, substd_output_type) {
            // If the function returns nil/bot, there is no real return
            // value, so do not set `llretslotptr`.
            if !skip_retptr || fcx.caller_expects_out_pointer {
                // Otherwise, we normally allocate the llretslotptr, unless we
                // have been instructed to skip it for immediate return
                // values.
                fcx.llretslotptr.set(Some(make_return_slot_pointer(fcx, substd_output_type)));
            }
        }
    }

    // Create the drop-flag hints for every unfragmented path in the function.
    let tcx = fcx.ccx.tcx();
    let fn_did = DefId { krate: LOCAL_CRATE, node: fcx.id };
    let mut hints = fcx.lldropflag_hints.borrow_mut();
    let fragment_infos = tcx.fragment_infos.borrow();

    // Intern table for drop-flag hint datums.
    let mut seen = HashMap::new();

    if let Some(fragment_infos) = fragment_infos.get(&fn_did) {
        for &info in fragment_infos {

            let make_datum = |id| {
                let init_val = C_u8(fcx.ccx, adt::DTOR_NEEDED_HINT);
                let llname = &format!("dropflag_hint_{}", id);
                debug!("adding hint {}", llname);
                let ty = tcx.types.u8;
                let ptr = alloc_ty(entry_bcx, ty, llname);
                Store(entry_bcx, init_val, ptr);
                let flag = datum::Lvalue::new_dropflag_hint("base::init_function");
                datum::Datum::new(ptr, ty, flag)
            };

            let (var, datum) = match info {
                ty::FragmentInfo::Moved { var, .. } |
                ty::FragmentInfo::Assigned { var, .. } => {
                    let datum = seen.get(&var).cloned().unwrap_or_else(|| {
                        let datum = make_datum(var);
                        seen.insert(var, datum.clone());
                        datum
                    });
                    (var, datum)
                }
            };
            match info {
                ty::FragmentInfo::Moved { move_expr: expr_id, .. } => {
                    debug!("FragmentInfo::Moved insert drop hint for {}", expr_id);
                    hints.insert(expr_id, DropHint::new(var, datum));
                }
                ty::FragmentInfo::Assigned { assignee_id: expr_id, .. } => {
                    debug!("FragmentInfo::Assigned insert drop hint for {}", expr_id);
                    hints.insert(expr_id, DropHint::new(var, datum));
                }
            }
        }
    }

    entry_bcx
}
/// Performs setup on a newly created function, creating the entry scope block
/// and allocating space for the return pointer.
Performs setup on a newly created function, creating the entry scope block
and allocating space for the return pointer.
Performs setup on a newly created function creating the entry scope block and allocating space for the return pointer .
pub fn init_function<'a, 'tcx>(fcx: &'a FunctionContext<'a, 'tcx>,
                               skip_retptr: bool,
                               output: ty::FnOutput<'tcx>)
                               -> Block<'a, 'tcx> {
    let entry_bcx = fcx.new_temp_block("entry-block");
    // Use a dummy instruction as the insertion point for all allocas.
    // This is later removed in FunctionContext::cleanup.
    fcx.alloca_insert_pt.set(Some(unsafe {
        Load(entry_bcx, C_null(Type::i8p(fcx.ccx)));
        llvm::LLVMGetFirstInstruction(entry_bcx.llbb)
    }));
    if let ty::FnConverging(output_type) = output {
        // This shouldn't need to recompute the return type,
        // as new_fn_ctxt did it already.
        let substd_output_type = fcx.monomorphize(&output_type);
        if !return_type_is_void(fcx.ccx, substd_output_type) {
            // If the function returns nil/bot, there is no real return
            // value, so do not set `llretslotptr`.
            if !skip_retptr || fcx.caller_expects_out_pointer {
                // Otherwise, we normally allocate the llretslotptr, unless we
                // have been instructed to skip it for immediate return
                // values.
                fcx.llretslotptr.set(Some(make_return_slot_pointer(fcx, substd_output_type)));
            }
        }
    }
    // Create the drop-flag hints for every unfragmented path in the function.
    let tcx = fcx.ccx.tcx();
    let fn_did = DefId { krate: LOCAL_CRATE, node: fcx.id };
    let mut hints = fcx.lldropflag_hints.borrow_mut();
    let fragment_infos = tcx.fragment_infos.borrow();
    // Intern table for drop-flag hint datums.
    let mut seen = HashMap::new();
    if let Some(fragment_infos) = fragment_infos.get(&fn_did) {
        for &info in fragment_infos {
            let make_datum = |id| {
                let init_val = C_u8(fcx.ccx, adt::DTOR_NEEDED_HINT);
                let llname = &format!("dropflag_hint_{}", id);
                debug!("adding hint {}", llname);
                let ty = tcx.types.u8;
                let ptr = alloc_ty(entry_bcx, ty, llname);
                Store(entry_bcx, init_val, ptr);
                let flag = datum::Lvalue::new_dropflag_hint("base::init_function");
                datum::Datum::new(ptr, ty, flag)
            };
            let (var, datum) = match info {
                ty::FragmentInfo::Moved { var, .. } |
                ty::FragmentInfo::Assigned { var, .. } => {
                    let datum = seen.get(&var).cloned().unwrap_or_else(|| {
                        let datum = make_datum(var);
                        seen.insert(var, datum.clone());
                        datum
                    });
                    (var, datum)
                }
            };
            match info {
                ty::FragmentInfo::Moved { move_expr: expr_id, .. } => {
                    debug!("FragmentInfo::Moved insert drop hint for {}", expr_id);
                    hints.insert(expr_id, DropHint::new(var, datum));
                }
                ty::FragmentInfo::Assigned { assignee_id: expr_id, .. } => {
                    debug!("FragmentInfo::Assigned insert drop hint for {}", expr_id);
                    hints.insert(expr_id, DropHint::new(var, datum));
                }
            }
        }
    }
    entry_bcx
}
pub fn init_function < ' a , ' tcx > ( fcx : & ' a FunctionContext < ' a , ' tcx > , skip_retptr : bool , output : ty :: FnOutput < ' tcx > ) -> Block < ' a , ' tcx > { let entry_bcx = fcx . new_temp_block ( " " ) ; // Use a dummy instruction as the insertion point for all allocas. // This is later removed in FunctionContext::cleanup. fcx . alloca_insert_pt . set ( Some ( unsafe { Load ( entry_bcx , C_null ( Type :: i8p ( fcx . ccx ) ) ) ; llvm :: LLVMGetFirstInstruction ( entry_bcx . llbb ) } ) ) ; if let ty :: FnConverging ( output_type ) = output { // This shouldn't need to recompute the return type, // as new_fn_ctxt did it already. let substd_output_type = fcx . monomorphize ( & output_type ) ; if ! return_type_is_void ( fcx . ccx , substd_output_type ) { // If the function returns nil/bot, there is no real return // value, so do not set `llretslotptr`. if ! skip_retptr || fcx . caller_expects_out_pointer { // Otherwise, we normally allocate the llretslotptr, unless we // have been instructed to skip it for immediate return // values. fcx . llretslotptr . set ( Some ( make_return_slot_pointer ( fcx , substd_output_type ) ) ) ; } } } // Create the drop-flag hints for every unfragmented path in the function. let tcx = fcx . ccx . tcx ( ) ; let fn_did = DefId { krate : LOCAL_CRATE , node : fcx . id } ; let mut hints = fcx . lldropflag_hints . borrow_mut ( ) ; let fragment_infos = tcx . fragment_infos . borrow ( ) ; // Intern table for drop-flag hint datums. let mut seen = HashMap :: new ( ) ; if let Some ( fragment_infos ) = fragment_infos . get ( & fn_did ) { for & info in fragment_infos { let make_datum = | id | { let init_val = C_u8 ( fcx . ccx , adt :: DTOR_NEEDED_HINT ) ; let llname = & format ! ( " " id ) ; debug ! ( " " llname ) ; let ty = tcx . types . u8 ; let ptr = alloc_ty ( entry_bcx , ty , llname ) ; Store ( entry_bcx , init_val , ptr ) ; let flag = datum :: Lvalue :: new_dropflag_hint ( " " ) ; datum :: Datum :: new ( ptr , ty , flag ) } ; let ( var , datum ) = match info { ty :: FragmentInfo :: Moved { var , .. } | ty :: FragmentInfo :: Assigned { var , .. } => { let datum = seen . get ( & var ) . cloned ( ) . unwrap_or_else ( | | { let datum = make_datum ( var ) ; seen . insert ( var , datum . clone ( ) ) ; datum } ) ; ( var , datum ) } } ; match info { ty :: FragmentInfo :: Moved { move_expr : expr_id , .. } => { debug ! ( " " expr_id ) ; hints . insert ( expr_id , DropHint :: new ( var , datum ) ) ; } ty :: FragmentInfo :: Assigned { assignee_id : expr_id , .. } => { debug ! ( " " expr_id ) ; hints . insert ( expr_id , DropHint :: new ( var , datum ) ) ; } } } } entry_bcx }
Performs setup on a newly created function, creating the entry scope block
and allocating space for the return pointer.
Performs setup on a newly created function creating the entry scope block and allocating space for the return pointer .
fcx
&'a FunctionContext<'a, 'tcx>
skip_retptr
bool
output
ty::FnOutput<'tcx>
fcx
&'a FunctionContext<'a, 'tcx>
skip_retptr
bool
output
ty::FnOutput<'tcx>