rustc_codegen_ssa/
mono_item.rs

1use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
2use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
3use rustc_middle::ty::layout::HasTyCtxt;
4use tracing::debug;
5
6use crate::base;
7use crate::mir::naked_asm;
8use crate::traits::*;
9
10pub trait MonoItemExt<'a, 'tcx> {
11    fn define<Bx: BuilderMethods<'a, 'tcx>>(
12        &self,
13        cx: &'a mut Bx::CodegenCx,
14        item_data: MonoItemData,
15    );
16    fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
17        &self,
18        cx: &'a Bx::CodegenCx,
19        linkage: Linkage,
20        visibility: Visibility,
21    );
22    fn to_raw_string(&self) -> String;
23}
24
25impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
26    fn define<Bx: BuilderMethods<'a, 'tcx>>(
27        &self,
28        cx: &'a mut Bx::CodegenCx,
29        item_data: MonoItemData,
30    ) {
31        debug!(
32            "BEGIN IMPLEMENTING '{} ({})' in cgu {}",
33            self,
34            self.to_raw_string(),
35            cx.codegen_unit().name()
36        );
37
38        match *self {
39            MonoItem::Static(def_id) => {
40                cx.codegen_static(def_id);
41            }
42            MonoItem::GlobalAsm(item_id) => {
43                base::codegen_global_asm(cx, item_id);
44            }
45            MonoItem::Fn(instance) => {
46                if cx
47                    .tcx()
48                    .codegen_fn_attrs(instance.def_id())
49                    .flags
50                    .contains(CodegenFnAttrFlags::NAKED)
51                {
52                    naked_asm::codegen_naked_asm::<Bx::CodegenCx>(cx, instance, item_data);
53                } else {
54                    base::codegen_instance::<Bx>(cx, instance);
55                }
56            }
57        }
58
59        debug!(
60            "END IMPLEMENTING '{} ({})' in cgu {}",
61            self,
62            self.to_raw_string(),
63            cx.codegen_unit().name()
64        );
65    }
66
67    fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
68        &self,
69        cx: &'a Bx::CodegenCx,
70        linkage: Linkage,
71        visibility: Visibility,
72    ) {
73        debug!(
74            "BEGIN PREDEFINING '{} ({})' in cgu {}",
75            self,
76            self.to_raw_string(),
77            cx.codegen_unit().name()
78        );
79
80        let symbol_name = self.symbol_name(cx.tcx()).name;
81
82        debug!("symbol {symbol_name}");
83
84        match *self {
85            MonoItem::Static(def_id) => {
86                cx.predefine_static(def_id, linkage, visibility, symbol_name);
87            }
88            MonoItem::Fn(instance) => {
89                let attrs = cx.tcx().codegen_fn_attrs(instance.def_id());
90
91                if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
92                    // do not define this function; it will become a global assembly block
93                } else {
94                    cx.predefine_fn(instance, linkage, visibility, symbol_name);
95                };
96            }
97            MonoItem::GlobalAsm(..) => {}
98        }
99
100        debug!(
101            "END PREDEFINING '{} ({})' in cgu {}",
102            self,
103            self.to_raw_string(),
104            cx.codegen_unit().name()
105        );
106    }
107
108    fn to_raw_string(&self) -> String {
109        match *self {
110            MonoItem::Fn(instance) => {
111                format!("Fn({:?}, {})", instance.def, instance.args.as_ptr().addr())
112            }
113            MonoItem::Static(id) => format!("Static({id:?})"),
114            MonoItem::GlobalAsm(id) => format!("GlobalAsm({id:?})"),
115        }
116    }
117}