) -> PassMode {
if ty.sty == tcx.mk_nil().sty {
if is_return {
- //if false {
+ //if false {
PassMode::NoPass
} else {
PassMode::ByRef
tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &sig)
}
+fn get_function_name_and_sig<'a, 'tcx>(
+ tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ inst: Instance<'tcx>,
+) -> (String, Signature) {
+ assert!(!inst.substs.needs_infer() && !inst.substs.has_param_types());
+ let fn_ty = inst.ty(tcx);
+ let sig = cton_sig_from_fn_ty(tcx, fn_ty);
+ let def_path_based_names =
+ ::rustc_mir::monomorphize::item::DefPathBasedNames::new(tcx, false, false);
+ let mut name = String::new();
+ def_path_based_names.push_instance_as_string(inst, &mut name);
+ (name, sig)
+}
+
+impl<'a, 'tcx: 'a> CodegenCx<'a, 'tcx, CurrentBackend> {
+ pub fn predefine_function(&mut self, inst: Instance<'tcx>) -> (FuncId, Function) {
+ let (name, sig) = crate::abi::get_function_name_and_sig(self.tcx, inst);
+ let func_id = self
+ .module
+ .declare_function(&name, Linkage::Export, &sig)
+ .unwrap();
+ let func =
+ Function::with_name_signature(ExternalName::user(0, func_id.index() as u32), sig);
+ (func_id, func)
+ }
+}
+
impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
/// Instance must be monomorphized
pub fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef {
- assert!(!inst.substs.needs_infer() && !inst.substs.has_param_types());
- let fn_ty = inst.ty(self.tcx);
- let sig = cton_sig_from_fn_ty(self.tcx, fn_ty);
- let def_path_based_names =
- ::rustc_mir::monomorphize::item::DefPathBasedNames::new(self.tcx, false, false);
- let mut name = String::new();
- def_path_based_names.push_instance_as_string(inst, &mut name);
+ let (name, sig) = get_function_name_and_sig(self.tcx, inst);
let func_id = self
.module
.declare_function(&name, Linkage::Import, &sig)
.chain(
args.into_iter()
.map(|arg| match get_pass_mode(fx.tcx, sig.abi, arg.layout().ty, false) {
- PassMode::NoPass => unimplemented!("pass mode nopass"),
- PassMode::ByVal(_) => arg.load_value(fx),
- PassMode::ByRef => arg.force_stack(fx),
- }),
+ PassMode::NoPass => unimplemented!("pass mode nopass"),
+ PassMode::ByVal(_) => arg.load_value(fx),
+ PassMode::ByRef => arg.force_stack(fx),
+ }),
).collect::<Vec<_>>();
let inst = match func {
ty::ParamEnv::reveal_all(),
&fn_ty,
);
- let sig = cton_sig_from_fn_ty(tcx, fn_ty);
-
- let func_id = {
- // WARNING: keep in sync with FunctionCx::get_function_ref
- let def_path_based_names =
- ::rustc_mir::monomorphize::item::DefPathBasedNames::new(
- cx.tcx, false, false,
- );
- let mut name = String::new();
- def_path_based_names.push_instance_as_string(inst, &mut name);
- cx.module
- .declare_function(&name, Linkage::Export, &sig)
- .unwrap()
- };
- let mut f = Function::with_name_signature(
- ExternalName::user(0, func_id.index() as u32),
- sig,
- );
+ let (func_id, mut func) = cx.predefine_function(inst);
- let comments = trans_fn(cx, &mut f, inst);
+ let comments = trans_fn(cx, &mut func, inst);
let mut writer = crate::pretty_clif::CommentWriter(comments);
let mut cton = String::new();
- ::cranelift::codegen::write::decorate_function(&mut writer, &mut cton, &f, None)
+ ::cranelift::codegen::write::decorate_function(&mut writer, &mut cton, &func, None)
.unwrap();
tcx.sess.warn(&cton);
let flags = settings::Flags::new(settings::builder());
- match ::cranelift::codegen::verify_function(&f, &flags) {
+ match ::cranelift::codegen::verify_function(&func, &flags) {
Ok(_) => {}
Err(err) => {
tcx.sess.err(&format!("{:?}", err));
let pretty_error =
::cranelift::codegen::print_errors::pretty_verifier_error(
- &f,
+ &func,
None,
Some(Box::new(writer)),
&err,
}
}
- context.func = f;
+ context.func = func;
// TODO: cranelift doesn't yet support some of the things needed
if false {
cx.module.define_function(func_id, context).unwrap();