5 use rustc_middle::mir::mono::MonoItem;
6 use rustc_middle::mir::mono::{Linkage, Visibility};
8 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
9 use rustc_middle::ty::Instance;
11 pub trait MonoItemExt<'a, 'tcx> {
12 fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx);
13 fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
15 cx: &'a Bx::CodegenCx,
17 visibility: Visibility,
19 fn to_raw_string(&self) -> String;
22 impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
23 fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) {
25 "BEGIN IMPLEMENTING '{} ({})' in cgu {}",
28 cx.codegen_unit().name()
32 MonoItem::Static(def_id) => {
33 cx.codegen_static(def_id, cx.tcx().is_mutable_static(def_id));
35 MonoItem::GlobalAsm(item_id) => {
36 let item = cx.tcx().hir().item(item_id);
37 if let hir::ItemKind::GlobalAsm(ref asm) = item.kind {
38 let operands: Vec<_> = asm
41 .map(|(op, op_sp)| match *op {
42 hir::InlineAsmOperand::Const { ref anon_const } => {
43 let anon_const_def_id =
44 cx.tcx().hir().local_def_id(anon_const.hir_id).to_def_id();
46 cx.tcx().const_eval_poly(anon_const_def_id).unwrap_or_else(
47 |_| span_bug!(*op_sp, "asm const cannot be resolved"),
51 .typeck_body(anon_const.body)
52 .node_type(anon_const.hir_id);
53 let string = common::asm_const_to_str(
59 GlobalAsmOperandRef::Const { string }
61 hir::InlineAsmOperand::SymFn { ref anon_const } => {
64 .typeck_body(anon_const.body)
65 .node_type(anon_const.hir_id);
66 let instance = match ty.kind() {
67 &ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
68 _ => span_bug!(*op_sp, "asm sym is not a function"),
71 GlobalAsmOperandRef::SymFn { instance }
73 hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
74 GlobalAsmOperandRef::SymStatic { def_id }
76 hir::InlineAsmOperand::In { .. }
77 | hir::InlineAsmOperand::Out { .. }
78 | hir::InlineAsmOperand::InOut { .. }
79 | hir::InlineAsmOperand::SplitInOut { .. } => {
80 span_bug!(*op_sp, "invalid operand type for global_asm!")
85 cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
87 span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
90 MonoItem::Fn(instance) => {
91 base::codegen_instance::<Bx>(&cx, instance);
96 "END IMPLEMENTING '{} ({})' in cgu {}",
99 cx.codegen_unit().name()
103 fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
105 cx: &'a Bx::CodegenCx,
107 visibility: Visibility,
110 "BEGIN PREDEFINING '{} ({})' in cgu {}",
112 self.to_raw_string(),
113 cx.codegen_unit().name()
116 let symbol_name = self.symbol_name(cx.tcx()).name;
118 debug!("symbol {}", &symbol_name);
121 MonoItem::Static(def_id) => {
122 cx.predefine_static(def_id, linkage, visibility, &symbol_name);
124 MonoItem::Fn(instance) => {
125 cx.predefine_fn(instance, linkage, visibility, &symbol_name);
127 MonoItem::GlobalAsm(..) => {}
131 "END PREDEFINING '{} ({})' in cgu {}",
133 self.to_raw_string(),
134 cx.codegen_unit().name()
138 fn to_raw_string(&self) -> String {
140 MonoItem::Fn(instance) => {
141 format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr().addr())
143 MonoItem::Static(id) => format!("Static({:?})", id),
144 MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),