1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
use crate::base; use crate::common; use crate::traits::*; use rustc_hir as hir; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::layout::HasTyCtxt; use rustc_target::abi::LayoutOf; pub trait MonoItemExt<'a, 'tcx> { fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx); fn predefine<Bx: BuilderMethods<'a, 'tcx>>( &self, cx: &'a Bx::CodegenCx, linkage: Linkage, visibility: Visibility, ); fn to_raw_string(&self) -> String; } impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) { debug!( "BEGIN IMPLEMENTING '{} ({})' in cgu {}", self, self.to_raw_string(), cx.codegen_unit().name() ); match *self { MonoItem::Static(def_id) => { cx.codegen_static(def_id, cx.tcx().is_mutable_static(def_id)); } MonoItem::GlobalAsm(item_id) => { let item = cx.tcx().hir().item(item_id); if let hir::ItemKind::GlobalAsm(ref asm) = item.kind { let operands: Vec<_> = asm .operands .iter() .map(|(op, op_sp)| match *op { hir::InlineAsmOperand::Const { ref anon_const } => { let anon_const_def_id = cx.tcx().hir().local_def_id(anon_const.hir_id).to_def_id(); let const_value = cx.tcx().const_eval_poly(anon_const_def_id).unwrap_or_else( |_| span_bug!(*op_sp, "asm const cannot be resolved"), ); let ty = cx .tcx() .typeck_body(anon_const.body) .node_type(anon_const.hir_id); let string = common::asm_const_to_str( cx.tcx(), *op_sp, const_value, cx.layout_of(ty), ); GlobalAsmOperandRef::Const { string } } _ => span_bug!(*op_sp, "invalid operand type for global_asm!"), }) .collect(); cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans); } else { span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type") } } MonoItem::Fn(instance) => { base::codegen_instance::<Bx>(&cx, instance); } } debug!( "END IMPLEMENTING '{} ({})' in cgu {}", self, self.to_raw_string(), cx.codegen_unit().name() ); } fn predefine<Bx: BuilderMethods<'a, 'tcx>>( &self, cx: &'a Bx::CodegenCx, linkage: Linkage, visibility: Visibility, ) { debug!( "BEGIN PREDEFINING '{} ({})' in cgu {}", self, self.to_raw_string(), cx.codegen_unit().name() ); let symbol_name = self.symbol_name(cx.tcx()).name; debug!("symbol {}", &symbol_name); match *self { MonoItem::Static(def_id) => { cx.predefine_static(def_id, linkage, visibility, &symbol_name); } MonoItem::Fn(instance) => { cx.predefine_fn(instance, linkage, visibility, &symbol_name); } MonoItem::GlobalAsm(..) => {} } debug!( "END PREDEFINING '{} ({})' in cgu {}", self, self.to_raw_string(), cx.codegen_unit().name() ); } fn to_raw_string(&self) -> String { match *self { MonoItem::Fn(instance) => { format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr() as usize) } MonoItem::Static(id) => format!("Static({:?})", id), MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id), } } }