]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_ssa/src/mono_item.rs
Rollup merge of #104439 - ferrocene:pa-generate-copyright, r=pnkfelix
[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;
8 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
9 use rustc_middle::ty::Instance;
10
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>>(
14         &self,
15         cx: &'a Bx::CodegenCx,
16         linkage: Linkage,
17         visibility: Visibility,
18     );
19     fn to_raw_string(&self) -> String;
20 }
21
22 impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
23     fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) {
24         debug!(
25             "BEGIN IMPLEMENTING '{} ({})' in cgu {}",
26             self,
27             self.to_raw_string(),
28             cx.codegen_unit().name()
29         );
30
31         match *self {
32             MonoItem::Static(def_id) => {
33                 cx.codegen_static(def_id, cx.tcx().is_mutable_static(def_id));
34             }
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
39                         .operands
40                         .iter()
41                         .map(|(op, op_sp)| match *op {
42                             hir::InlineAsmOperand::Const { ref anon_const } => {
43                                 let const_value = cx
44                                     .tcx()
45                                     .const_eval_poly(anon_const.def_id.to_def_id())
46                                     .unwrap_or_else(|_| {
47                                         span_bug!(*op_sp, "asm const cannot be resolved")
48                                     });
49                                 let ty = cx
50                                     .tcx()
51                                     .typeck_body(anon_const.body)
52                                     .node_type(anon_const.hir_id);
53                                 let string = common::asm_const_to_str(
54                                     cx.tcx(),
55                                     *op_sp,
56                                     const_value,
57                                     cx.layout_of(ty),
58                                 );
59                                 GlobalAsmOperandRef::Const { string }
60                             }
61                             hir::InlineAsmOperand::SymFn { ref anon_const } => {
62                                 let ty = cx
63                                     .tcx()
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"),
69                                 };
70
71                                 GlobalAsmOperandRef::SymFn { instance }
72                             }
73                             hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
74                                 GlobalAsmOperandRef::SymStatic { def_id }
75                             }
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!")
81                             }
82                         })
83                         .collect();
84
85                     cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
86                 } else {
87                     span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
88                 }
89             }
90             MonoItem::Fn(instance) => {
91                 base::codegen_instance::<Bx>(&cx, instance);
92             }
93         }
94
95         debug!(
96             "END IMPLEMENTING '{} ({})' in cgu {}",
97             self,
98             self.to_raw_string(),
99             cx.codegen_unit().name()
100         );
101     }
102
103     fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
104         &self,
105         cx: &'a Bx::CodegenCx,
106         linkage: Linkage,
107         visibility: Visibility,
108     ) {
109         debug!(
110             "BEGIN PREDEFINING '{} ({})' in cgu {}",
111             self,
112             self.to_raw_string(),
113             cx.codegen_unit().name()
114         );
115
116         let symbol_name = self.symbol_name(cx.tcx()).name;
117
118         debug!("symbol {}", &symbol_name);
119
120         match *self {
121             MonoItem::Static(def_id) => {
122                 cx.predefine_static(def_id, linkage, visibility, &symbol_name);
123             }
124             MonoItem::Fn(instance) => {
125                 cx.predefine_fn(instance, linkage, visibility, &symbol_name);
126             }
127             MonoItem::GlobalAsm(..) => {}
128         }
129
130         debug!(
131             "END PREDEFINING '{} ({})' in cgu {}",
132             self,
133             self.to_raw_string(),
134             cx.codegen_unit().name()
135         );
136     }
137
138     fn to_raw_string(&self) -> String {
139         match *self {
140             MonoItem::Fn(instance) => {
141                 format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr().addr())
142             }
143             MonoItem::Static(id) => format!("Static({:?})", id),
144             MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),
145         }
146     }
147 }