]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_codegen_ssa/src/mono_item.rs
New upstream version 1.54.0+dfsg1
[rustc.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 }