rustc_middle/middle/
exported_symbols.rs

1use rustc_hir::def_id::{DefId, LOCAL_CRATE};
2use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable};
3
4use crate::ty::{self, GenericArgsRef, Ty, TyCtxt};
5
6/// The SymbolExportLevel of a symbols specifies from which kinds of crates
7/// the symbol will be exported. `C` symbols will be exported from any
8/// kind of crate, including cdylibs which export very few things.
9/// `Rust` will only be exported if the crate produced is a Rust
10/// dylib.
11#[derive(Eq, PartialEq, Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
12pub enum SymbolExportLevel {
13    C,
14    Rust,
15}
16
17impl SymbolExportLevel {
18    pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
19        threshold == SymbolExportLevel::Rust // export everything from Rust dylibs
20          || self == SymbolExportLevel::C
21    }
22}
23
24/// Kind of exported symbols.
25#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable, Hash)]
26pub enum SymbolExportKind {
27    Text,
28    Data,
29    Tls,
30}
31
32/// The `SymbolExportInfo` of a symbols specifies symbol-related information
33/// that is relevant to code generation and linking.
34///
35/// The difference between `used` and `rustc_std_internal_symbol` is that the
36/// former is exported by LTO while the latter isn't.
37#[derive(Eq, PartialEq, Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
38pub struct SymbolExportInfo {
39    pub level: SymbolExportLevel,
40    pub kind: SymbolExportKind,
41    /// Was the symbol marked as `#[used(compiler)]` or `#[used(linker)]`?
42    pub used: bool,
43    /// Was the symbol marked as `#[rustc_std_internal_symbol]`?
44    pub rustc_std_internal_symbol: bool,
45}
46
47#[derive(Eq, PartialEq, Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
48pub enum ExportedSymbol<'tcx> {
49    NonGeneric(DefId),
50    Generic(DefId, GenericArgsRef<'tcx>),
51    DropGlue(Ty<'tcx>),
52    AsyncDropGlueCtorShim(Ty<'tcx>),
53    AsyncDropGlue(DefId, Ty<'tcx>),
54    ThreadLocalShim(DefId),
55    NoDefId(ty::SymbolName<'tcx>),
56}
57
58impl<'tcx> ExportedSymbol<'tcx> {
59    /// This is the symbol name of an instance if it is instantiated in the
60    /// local crate.
61    pub fn symbol_name_for_local_instance(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName<'tcx> {
62        match *self {
63            ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)),
64            ExportedSymbol::Generic(def_id, args) => {
65                tcx.symbol_name(ty::Instance::new_raw(def_id, args))
66            }
67            ExportedSymbol::DropGlue(ty) => {
68                tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
69            }
70            ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
71                tcx.symbol_name(ty::Instance::resolve_async_drop_in_place(tcx, ty))
72            }
73            ExportedSymbol::AsyncDropGlue(def_id, ty) => {
74                tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty))
75            }
76            ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance {
77                def: ty::InstanceKind::ThreadLocalShim(def_id),
78                args: ty::GenericArgs::empty(),
79            }),
80            ExportedSymbol::NoDefId(symbol_name) => symbol_name,
81        }
82    }
83}
84
85pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String {
86    format!(
87        "rust_metadata_{}_{:08x}",
88        tcx.crate_name(LOCAL_CRATE),
89        tcx.stable_crate_id(LOCAL_CRATE),
90    )
91}