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