pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>,
                                           args: &[hir::Arg],
                                           arg_tys: &[Ty<'tcx>],
                                           has_tupled_arg: bool,
                                           arg_scope: cleanup::CustomScopeIndex)
                                           -> Block<'a, 'tcx> {
    let _icx = push_ctxt("create_datums_for_fn_args");
    let fcx = bcx.fcx;
    let arg_scope_id = cleanup::CustomScope(arg_scope);

    // Return an array wrapping the ValueRefs that we get from `get_param` for
    // each argument into datums.
    //
    // 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
    // cleanup and for better interaction with LLVM's debug info.  So, if
    // the argument would be passed by value, we store it into an alloca.
    // This alloca should be optimized away by LLVM's mem-to-reg pass in
    // the event it's not truly needed.
    let mut idx = fcx.arg_offset() as c_uint;
    for (i, &arg_ty) in arg_tys.iter().enumerate() {
        let arg_datum = if !has_tupled_arg || i < arg_tys.len() - 1 {
            if type_of::arg_is_indirect(bcx.ccx(), arg_ty)
                    && bcx.sess().opts.debuginfo != FullDebugInfo {
                // Don't copy an indirect argument to an alloca, the caller
                // already put it in a temporary alloca and gave it up, unless
                // we emit extra-debug-info, which requires local allocas :(.
                let llarg = get_param(fcx.llfn, idx);
                idx += 1;
                bcx.fcx.schedule_lifetime_end(arg_scope_id, llarg);
                bcx.fcx.schedule_drop_mem(arg_scope_id, llarg, arg_ty, None);

                datum::Datum::new(llarg, arg_ty, datum::Lvalue::new("create_datum_for_fn_args"))
            } else if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
                let data = get_param(fcx.llfn, idx);
                let extra = get_param(fcx.llfn, idx + 1);
                idx += 2;
                unpack_datum!(bcx, datum::lvalue_scratch_datum(bcx, arg_ty, "",
                                                        arg_scope_id, (data, extra),
                                                        |(data, extra), bcx, dst| {
                    Store(bcx, data, expr::get_dataptr(bcx, dst));
                    Store(bcx, extra, expr::get_meta(bcx, dst));
                    bcx
                }))
            } else {
                let llarg = get_param(fcx.llfn, idx);
                idx += 1;
                let tmp = datum::Datum::new(llarg, arg_ty, arg_kind(fcx, arg_ty));
                unpack_datum!(bcx, datum::lvalue_scratch_datum(bcx, arg_ty, "",
                                                           arg_scope_id, tmp,
                                                           |tmp, bcx, dst| tmp.store_to(bcx, dst)))
            }
        } else {
            // FIXME(pcwalton): Reduce the amount of code bloat this is responsible for.
            match arg_ty.sty {
                ty::TyTuple(ref tupled_arg_tys) => {
                    unpack_datum!(bcx,
                                  datum::lvalue_scratch_datum(bcx,
                                                              arg_ty,
                                                              "tupled_args",
                                                              arg_scope_id,
                                                              (),
                                                              |(),
                                                               mut bcx,
                                                               llval| {
                        for (j, &tupled_arg_ty) in
                                    tupled_arg_tys.iter().enumerate() {
                            let lldest = StructGEP(bcx, llval, j);
                            if common::type_is_fat_ptr(bcx.tcx(), tupled_arg_ty) {
                                let data = get_param(bcx.fcx.llfn, idx);
                                let extra = get_param(bcx.fcx.llfn, idx + 1);
                                Store(bcx, data, expr::get_dataptr(bcx, lldest));
                                Store(bcx, extra, expr::get_meta(bcx, lldest));
                                idx += 2;
                            } else {
                                let datum = datum::Datum::new(
                                    get_param(bcx.fcx.llfn, idx),
                                    tupled_arg_ty,
                                    arg_kind(bcx.fcx, tupled_arg_ty));
                                idx += 1;
                                bcx = datum.store_to(bcx, lldest);
                            };
                        }
                        bcx
                    }))
                }
                _ => {
                    bcx.tcx().sess.bug("last argument of a function with \
                                        `rust-call` ABI isn't a tuple?!")
                }
            }
        };

        let pat = &*args[i].pat;
        bcx = if let Some(ident) = simple_identifier(&*pat) {
            // Generate nicer LLVM for the common case of fn a pattern
            // like `x: T`
            set_value_name(arg_datum.val, &bcx.name(ident.name));
            bcx.fcx.lllocals.borrow_mut().insert(pat.id, arg_datum);
            bcx
        } else {
            // General path. Copy out the values that are used in the
            // pattern.
            _match::bind_irrefutable_pat(bcx, pat, arg_datum.match_input(), arg_scope_id)
        };
        debuginfo::create_argument_metadata(bcx, &args[i]);
    }

    bcx
}
// create_datums_for_fn_args: creates lvalue datums for each of the
// incoming function arguments.
creates lvalue datums for each of the
incoming function arguments.
creates lvalue datums for each of the incoming function arguments .
pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>,
                                           args: &[hir::Arg],
                                           arg_tys: &[Ty<'tcx>],
                                           has_tupled_arg: bool,
                                           arg_scope: cleanup::CustomScopeIndex)
                                           -> Block<'a, 'tcx> {
    let _icx = push_ctxt("create_datums_for_fn_args");
    let fcx = bcx.fcx;
    let arg_scope_id = cleanup::CustomScope(arg_scope);
    // Return an array wrapping the ValueRefs that we get from `get_param` for
    // each argument into datums.
    //
    // 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
    // cleanup and for better interaction with LLVM's debug info.  So, if
    // the argument would be passed by value, we store it into an alloca.
    // This alloca should be optimized away by LLVM's mem-to-reg pass in
    // the event it's not truly needed.
    let mut idx = fcx.arg_offset() as c_uint;
    for (i, &arg_ty) in arg_tys.iter().enumerate() {
        let arg_datum = if !has_tupled_arg || i < arg_tys.len() - 1 {
            if type_of::arg_is_indirect(bcx.ccx(), arg_ty)
                    && bcx.sess().opts.debuginfo != FullDebugInfo {
                // Don't copy an indirect argument to an alloca, the caller
                // already put it in a temporary alloca and gave it up, unless
                // we emit extra-debug-info, which requires local allocas :(.
                let llarg = get_param(fcx.llfn, idx);
                idx += 1;
                bcx.fcx.schedule_lifetime_end(arg_scope_id, llarg);
                bcx.fcx.schedule_drop_mem(arg_scope_id, llarg, arg_ty, None);
                datum::Datum::new(llarg, arg_ty, datum::Lvalue::new("create_datum_for_fn_args"))
            } else if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
                let data = get_param(fcx.llfn, idx);
                let extra = get_param(fcx.llfn, idx + 1);
                idx += 2;
                unpack_datum!(bcx, datum::lvalue_scratch_datum(bcx, arg_ty, "",
                                                        arg_scope_id, (data, extra),
                                                        |(data, extra), bcx, dst| {
                    Store(bcx, data, expr::get_dataptr(bcx, dst));
                    Store(bcx, extra, expr::get_meta(bcx, dst));
                    bcx
                }))
            } else {
                let llarg = get_param(fcx.llfn, idx);
                idx += 1;
                let tmp = datum::Datum::new(llarg, arg_ty, arg_kind(fcx, arg_ty));
                unpack_datum!(bcx, datum::lvalue_scratch_datum(bcx, arg_ty, "",
                                                           arg_scope_id, tmp,
                                                           |tmp, bcx, dst| tmp.store_to(bcx, dst)))
            }
        } else {
            // FIXME(pcwalton): Reduce the amount of code bloat this is responsible for.
            match arg_ty.sty {
                ty::TyTuple(ref tupled_arg_tys) => {
                    unpack_datum!(bcx,
                                  datum::lvalue_scratch_datum(bcx,
                                                              arg_ty,
                                                              "tupled_args",
                                                              arg_scope_id,
                                                              (),
                                                              |(),
                                                               mut bcx,
                                                               llval| {
                        for (j, &tupled_arg_ty) in
                                    tupled_arg_tys.iter().enumerate() {
                            let lldest = StructGEP(bcx, llval, j);
                            if common::type_is_fat_ptr(bcx.tcx(), tupled_arg_ty) {
                                let data = get_param(bcx.fcx.llfn, idx);
                                let extra = get_param(bcx.fcx.llfn, idx + 1);
                                Store(bcx, data, expr::get_dataptr(bcx, lldest));
                                Store(bcx, extra, expr::get_meta(bcx, lldest));
                                idx += 2;
                            } else {
                                let datum = datum::Datum::new(
                                    get_param(bcx.fcx.llfn, idx),
                                    tupled_arg_ty,
                                    arg_kind(bcx.fcx, tupled_arg_ty));
                                idx += 1;
                                bcx = datum.store_to(bcx, lldest);
                            };
                        }
                        bcx
                    }))
                }
                _ => {
                    bcx.tcx().sess.bug("last argument of a function with \
                                        `rust-call` ABI isn't a tuple?!")
                }
            }
        };
        let pat = &*args[i].pat;
        bcx = if let Some(ident) = simple_identifier(&*pat) {
            // Generate nicer LLVM for the common case of fn a pattern
            // like `x: T`
            set_value_name(arg_datum.val, &bcx.name(ident.name));
            bcx.fcx.lllocals.borrow_mut().insert(pat.id, arg_datum);
            bcx
        } else {
            // General path. Copy out the values that are used in the
            // pattern.
            _match::bind_irrefutable_pat(bcx, pat, arg_datum.match_input(), arg_scope_id)
        };
        debuginfo::create_argument_metadata(bcx, &args[i]);
    }
    bcx
}
pub fn create_datums_for_fn_args < ' a , ' tcx > ( mut bcx : Block < ' a , ' tcx > , args : & [ hir :: Arg ] , arg_tys : & [ Ty < ' tcx > ] , has_tupled_arg : bool , arg_scope : cleanup :: CustomScopeIndex ) -> Block < ' a , ' tcx > { let _icx = push_ctxt ( " " ) ; let fcx = bcx . fcx ; let arg_scope_id = cleanup :: CustomScope ( arg_scope ) ; // Return an array wrapping the ValueRefs that we get from `get_param` for // each argument into datums. // // 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 // cleanup and for better interaction with LLVM's debug info.  So, if // the argument would be passed by value, we store it into an alloca. // This alloca should be optimized away by LLVM's mem-to-reg pass in // the event it's not truly needed. let mut idx = fcx . arg_offset ( ) as c_uint ; for ( i , & arg_ty ) in arg_tys . iter ( ) . enumerate ( ) { let arg_datum = if ! has_tupled_arg || i < arg_tys . len ( ) - 1 { if type_of :: arg_is_indirect ( bcx . ccx ( ) , arg_ty ) && bcx . sess ( ) . opts . debuginfo != FullDebugInfo { // Don't copy an indirect argument to an alloca, the caller // already put it in a temporary alloca and gave it up, unless // we emit extra-debug-info, which requires local allocas :(. let llarg = get_param ( fcx . llfn , idx ) ; idx += 1 ; bcx . fcx . schedule_lifetime_end ( arg_scope_id , llarg ) ; bcx . fcx . schedule_drop_mem ( arg_scope_id , llarg , arg_ty , None ) ; datum :: Datum :: new ( llarg , arg_ty , datum :: Lvalue :: new ( " " ) ) } else if common :: type_is_fat_ptr ( bcx . tcx ( ) , arg_ty ) { let data = get_param ( fcx . llfn , idx ) ; let extra = get_param ( fcx . llfn , idx + 1 ) ; idx += 2 ; unpack_datum ! ( bcx datum lvalue_scratch_datum ( bcx arg_ty " " arg_scope_id ( data extra ) ( data extra ) bcx dst { Store ( bcx data expr get_dataptr ( bcx dst ) ) Store ( bcx extra expr get_meta ( bcx dst ) ) bcx } ) ) } else { let llarg = get_param ( fcx . llfn , idx ) ; idx += 1 ; let tmp = datum :: Datum :: new ( llarg , arg_ty , arg_kind ( fcx , arg_ty ) ) ; unpack_datum ! ( bcx datum lvalue_scratch_datum ( bcx arg_ty " " arg_scope_id tmp tmp bcx dst tmp store_to ( bcx dst ) ) ) } } else { // FIXME(pcwalton): Reduce the amount of code bloat this is responsible for. match arg_ty . sty { ty :: TyTuple ( ref tupled_arg_tys ) => { unpack_datum ! ( bcx datum lvalue_scratch_datum ( bcx arg_ty " " arg_scope_id ( ) ( ) mut bcx llval { for ( j tupled_arg_ty ) in tupled_arg_tys iter ( ) enumerate ( ) { let lldest StructGEP ( bcx llval j ) if common type_is_fat_ptr ( bcx tcx ( ) tupled_arg_ty ) { let data get_param ( bcx fcx llfn idx ) let extra get_param ( bcx fcx llfn idx 1 ) Store ( bcx data expr get_dataptr ( bcx lldest ) ) Store ( bcx extra expr get_meta ( bcx lldest ) ) idx 2 } else { let datum datum Datum new ( get_param ( bcx fcx llfn idx ) tupled_arg_ty arg_kind ( bcx fcx tupled_arg_ty ) ) idx 1 bcx datum store_to ( bcx lldest ) } } bcx } ) ) } _ => { bcx . tcx ( ) . sess . bug ( " \
 " ) } } } ; let pat = & * args [ i ] . pat ; bcx = if let Some ( ident ) = simple_identifier ( & * pat ) { // Generate nicer LLVM for the common case of fn a pattern // like `x: T` set_value_name ( arg_datum . val , & bcx . name ( ident . name ) ) ; bcx . fcx . lllocals . borrow_mut ( ) . insert ( pat . id , arg_datum ) ; bcx } else { // General path. Copy out the values that are used in the // pattern. _match :: bind_irrefutable_pat ( bcx , pat , arg_datum . match_input ( ) , arg_scope_id ) } ; debuginfo :: create_argument_metadata ( bcx , & args [ i ] ) ; } bcx }
create_datums_for_fn_args: creates lvalue datums for each of the
incoming function arguments.
create_datums_for_fn_args : creates lvalue datums for each of the incoming function arguments .
bcx
Block<'a, 'tcx>
args
&[hir::Arg]
arg_tys
&[Ty<'tcx>]
has_tupled_arg
bool
arg_scope
cleanup::CustomScopeIndex
bcx
Block<'a, 'tcx>
args
&[hir::Arg]
arg_tys
&[Ty<'tcx>]
has_tupled_arg
bool
arg_scope
cleanup::CustomScopeIndex