]>
Commit | Line | Data |
---|---|---|
416331ca | 1 | use std::collections::hash_map::Entry::*; |
ba9703b0 | 2 | |
74b04a01 | 3 | use rustc_ast::expand::allocator::ALLOCATOR_METHODS; |
b7449926 | 4 | use rustc_data_structures::fingerprint::Fingerprint; |
dfeec247 XL |
5 | use rustc_data_structures::fx::FxHashMap; |
6 | use rustc_hir as hir; | |
17df50a5 | 7 | use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; |
dfeec247 | 8 | use rustc_hir::Node; |
e74abb32 | 9 | use rustc_index::vec::IndexVec; |
ba9703b0 XL |
10 | use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; |
11 | use rustc_middle::middle::exported_symbols::{ | |
12 | metadata_symbol_name, ExportedSymbol, SymbolExportLevel, | |
13 | }; | |
14 | use rustc_middle::ty::query::Providers; | |
15 | use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; | |
16 | use rustc_middle::ty::Instance; | |
17 | use rustc_middle::ty::{SymbolName, TyCtxt}; | |
cdc7bbd5 XL |
18 | use rustc_session::config::CrateType; |
19 | use rustc_target::spec::SanitizerSet; | |
ea8adc8c | 20 | |
dc9dc135 | 21 | pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { |
f9f354fc | 22 | crates_export_threshold(&tcx.sess.crate_types()) |
476ff2be SL |
23 | } |
24 | ||
f9f354fc | 25 | fn crate_export_threshold(crate_type: CrateType) -> SymbolExportLevel { |
ea8adc8c | 26 | match crate_type { |
f9f354fc XL |
27 | CrateType::Executable | CrateType::Staticlib | CrateType::ProcMacro | CrateType::Cdylib => { |
28 | SymbolExportLevel::C | |
29 | } | |
30 | CrateType::Rlib | CrateType::Dylib => SymbolExportLevel::Rust, | |
476ff2be | 31 | } |
ea8adc8c | 32 | } |
476ff2be | 33 | |
f9f354fc | 34 | pub fn crates_export_threshold(crate_types: &[CrateType]) -> SymbolExportLevel { |
dfeec247 XL |
35 | if crate_types |
36 | .iter() | |
37 | .any(|&crate_type| crate_export_threshold(crate_type) == SymbolExportLevel::Rust) | |
a1dfa0c6 | 38 | { |
ea8adc8c XL |
39 | SymbolExportLevel::Rust |
40 | } else { | |
41 | SymbolExportLevel::C | |
42 | } | |
43 | } | |
44 | ||
f9f354fc | 45 | fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<SymbolExportLevel> { |
0531ce1d XL |
46 | assert_eq!(cnum, LOCAL_CRATE); |
47 | ||
94b46f34 | 48 | if !tcx.sess.opts.output_types.should_codegen() { |
f9f354fc | 49 | return Default::default(); |
0531ce1d XL |
50 | } |
51 | ||
52 | // Check to see if this crate is a "special runtime crate". These | |
53 | // crates, implementation details of the standard library, typically | |
54 | // have a bunch of `pub extern` and `#[no_mangle]` functions as the | |
55 | // ABI between them. We don't want their symbols to have a `C` | |
56 | // export level, however, as they're just implementation details. | |
57 | // Down below we'll hardwire all of the symbols to the `Rust` export | |
58 | // level instead. | |
dfeec247 XL |
59 | let special_runtime_crate = |
60 | tcx.is_panic_runtime(LOCAL_CRATE) || tcx.is_compiler_builtins(LOCAL_CRATE); | |
0531ce1d | 61 | |
dfeec247 | 62 | let mut reachable_non_generics: DefIdMap<_> = tcx |
17df50a5 | 63 | .reachable_set(()) |
0531ce1d | 64 | .iter() |
3dfed10e | 65 | .filter_map(|&def_id| { |
0531ce1d XL |
66 | // We want to ignore some FFI functions that are not exposed from |
67 | // this crate. Reachable FFI functions can be lumped into two | |
68 | // categories: | |
69 | // | |
70 | // 1. Those that are included statically via a static library | |
0731742a | 71 | // 2. Those included otherwise (e.g., dynamically or via a framework) |
0531ce1d XL |
72 | // |
73 | // Although our LLVM module is not literally emitting code for the | |
74 | // statically included symbols, it's an export of our library which | |
75 | // needs to be passed on to the linker and encoded in the metadata. | |
76 | // | |
77 | // As a result, if this id is an FFI item (foreign item) then we only | |
78 | // let it through if it's included statically. | |
3dfed10e | 79 | match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) { |
b7449926 | 80 | Node::ForeignItem(..) => { |
60c5eb7d | 81 | tcx.is_statically_included_foreign_item(def_id).then_some(def_id) |
0531ce1d | 82 | } |
476ff2be | 83 | |
0531ce1d | 84 | // Only consider nodes that actually have exported symbols. |
ba9703b0 XL |
85 | Node::Item(&hir::Item { |
86 | kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn(..), | |
87 | .. | |
88 | }) | |
89 | | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => { | |
0531ce1d | 90 | let generics = tcx.generics_of(def_id); |
f035d41b XL |
91 | if !generics.requires_monomorphization(tcx) |
92 | // Functions marked with #[inline] are codegened with "internal" | |
93 | // linkage and are not exported unless marked with an extern | |
94 | // inidicator | |
95 | && (!Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx) | |
96 | || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator()) | |
dfeec247 | 97 | { |
0531ce1d XL |
98 | Some(def_id) |
99 | } else { | |
100 | None | |
101 | } | |
102 | } | |
103 | ||
dfeec247 | 104 | _ => None, |
3b2f2976 | 105 | } |
0531ce1d | 106 | }) |
83c7162d | 107 | .map(|def_id| { |
0531ce1d | 108 | let export_level = if special_runtime_crate { |
3dfed10e | 109 | let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name; |
0531ce1d XL |
110 | // We can probably do better here by just ensuring that |
111 | // it has hidden visibility rather than public | |
112 | // visibility, as this is primarily here to ensure it's | |
113 | // not stripped during LTO. | |
114 | // | |
115 | // In general though we won't link right if these | |
116 | // symbols are stripped, and LTO currently strips them. | |
3dfed10e XL |
117 | match name { |
118 | "rust_eh_personality" | |
119 | | "rust_eh_register_frames" | |
120 | | "rust_eh_unregister_frames" => | |
121 | SymbolExportLevel::C, | |
122 | _ => SymbolExportLevel::Rust, | |
0531ce1d XL |
123 | } |
124 | } else { | |
f9f354fc | 125 | symbol_export_level(tcx, def_id.to_def_id()) |
0531ce1d | 126 | }; |
dfeec247 XL |
127 | debug!( |
128 | "EXPORTED SYMBOL (local): {} ({:?})", | |
f9f354fc | 129 | tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())), |
dfeec247 XL |
130 | export_level |
131 | ); | |
f9f354fc | 132 | (def_id.to_def_id(), export_level) |
0531ce1d XL |
133 | }) |
134 | .collect(); | |
135 | ||
17df50a5 XL |
136 | if let Some(id) = tcx.proc_macro_decls_static(()) { |
137 | reachable_non_generics.insert(id.to_def_id(), SymbolExportLevel::C); | |
0531ce1d XL |
138 | } |
139 | ||
f9f354fc | 140 | reachable_non_generics |
83c7162d XL |
141 | } |
142 | ||
416331ca | 143 | fn is_reachable_non_generic_provider_local(tcx: TyCtxt<'_>, def_id: DefId) -> bool { |
83c7162d XL |
144 | let export_threshold = threshold(tcx); |
145 | ||
146 | if let Some(&level) = tcx.reachable_non_generics(def_id.krate).get(&def_id) { | |
147 | level.is_below_threshold(export_threshold) | |
148 | } else { | |
149 | false | |
0531ce1d | 150 | } |
83c7162d XL |
151 | } |
152 | ||
416331ca | 153 | fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> bool { |
83c7162d XL |
154 | tcx.reachable_non_generics(def_id.krate).contains_key(&def_id) |
155 | } | |
156 | ||
416331ca | 157 | fn exported_symbols_provider_local( |
f035d41b | 158 | tcx: TyCtxt<'tcx>, |
dc9dc135 | 159 | cnum: CrateNum, |
f035d41b | 160 | ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] { |
83c7162d XL |
161 | assert_eq!(cnum, LOCAL_CRATE); |
162 | ||
94b46f34 | 163 | if !tcx.sess.opts.output_types.should_codegen() { |
ba9703b0 | 164 | return &[]; |
83c7162d XL |
165 | } |
166 | ||
dfeec247 XL |
167 | let mut symbols: Vec<_> = tcx |
168 | .reachable_non_generics(LOCAL_CRATE) | |
169 | .iter() | |
170 | .map(|(&def_id, &level)| (ExportedSymbol::NonGeneric(def_id), level)) | |
171 | .collect(); | |
3b2f2976 | 172 | |
17df50a5 | 173 | if tcx.entry_fn(()).is_some() { |
3dfed10e | 174 | let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, "main")); |
0531ce1d XL |
175 | |
176 | symbols.push((exported_symbol, SymbolExportLevel::C)); | |
177 | } | |
178 | ||
136023e0 | 179 | if tcx.allocator_kind(()).is_some() { |
0531ce1d XL |
180 | for method in ALLOCATOR_METHODS { |
181 | let symbol_name = format!("__rust_{}", method.name); | |
3dfed10e | 182 | let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); |
0531ce1d XL |
183 | |
184 | symbols.push((exported_symbol, SymbolExportLevel::Rust)); | |
476ff2be | 185 | } |
0531ce1d | 186 | } |
476ff2be | 187 | |
cdc7bbd5 | 188 | if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() { |
0531ce1d XL |
189 | // These are weak symbols that point to the profile version and the |
190 | // profile name, which need to be treated as exported so LTO doesn't nix | |
191 | // them. | |
dfeec247 XL |
192 | const PROFILER_WEAK_SYMBOLS: [&str; 2] = |
193 | ["__llvm_profile_raw_version", "__llvm_profile_filename"]; | |
a1dfa0c6 XL |
194 | |
195 | symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| { | |
3dfed10e | 196 | let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); |
a1dfa0c6 XL |
197 | (exported_symbol, SymbolExportLevel::C) |
198 | })); | |
0531ce1d | 199 | } |
abe05a73 | 200 | |
f035d41b | 201 | if tcx.sess.opts.debugging_opts.sanitizer.contains(SanitizerSet::MEMORY) { |
dfeec247 XL |
202 | // Similar to profiling, preserve weak msan symbol during LTO. |
203 | const MSAN_WEAK_SYMBOLS: [&str; 2] = ["__msan_track_origins", "__msan_keep_going"]; | |
204 | ||
205 | symbols.extend(MSAN_WEAK_SYMBOLS.iter().map(|sym| { | |
3dfed10e | 206 | let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); |
dfeec247 XL |
207 | (exported_symbol, SymbolExportLevel::C) |
208 | })); | |
209 | } | |
210 | ||
f9f354fc | 211 | if tcx.sess.crate_types().contains(&CrateType::Dylib) { |
0531ce1d | 212 | let symbol_name = metadata_symbol_name(tcx); |
3dfed10e | 213 | let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); |
abe05a73 | 214 | |
0531ce1d XL |
215 | symbols.push((exported_symbol, SymbolExportLevel::Rust)); |
216 | } | |
217 | ||
b7449926 | 218 | if tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics() { |
ba9703b0 XL |
219 | use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility}; |
220 | use rustc_middle::ty::InstanceDef; | |
83c7162d XL |
221 | |
222 | // Normally, we require that shared monomorphizations are not hidden, | |
223 | // because if we want to re-use a monomorphization from a Rust dylib, it | |
224 | // needs to be exported. | |
225 | // However, on platforms that don't allow for Rust dylibs, having | |
226 | // external linkage is enough for monomorphization to be linked to. | |
29967ef6 | 227 | let need_visibility = tcx.sess.target.dynamic_linking && !tcx.sess.target.only_cdylib; |
83c7162d | 228 | |
17df50a5 | 229 | let (_, cgus) = tcx.collect_and_partition_mono_items(()); |
83c7162d | 230 | |
dfeec247 | 231 | for (mono_item, &(linkage, visibility)) in cgus.iter().flat_map(|cgu| cgu.items().iter()) { |
83c7162d XL |
232 | if linkage != Linkage::External { |
233 | // We can only re-use things with external linkage, otherwise | |
234 | // we'll get a linker error | |
dfeec247 | 235 | continue; |
83c7162d XL |
236 | } |
237 | ||
238 | if need_visibility && visibility == Visibility::Hidden { | |
239 | // If we potentially share things from Rust dylibs, they must | |
240 | // not be hidden | |
dfeec247 | 241 | continue; |
83c7162d XL |
242 | } |
243 | ||
dfeec247 | 244 | match *mono_item { |
3dfed10e | 245 | MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => { |
dfeec247 | 246 | if substs.non_erasable_generics().next().is_some() { |
3dfed10e | 247 | let symbol = ExportedSymbol::Generic(def.did, substs); |
dfeec247 XL |
248 | symbols.push((symbol, SymbolExportLevel::Rust)); |
249 | } | |
250 | } | |
251 | MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), substs }) => { | |
252 | // A little sanity-check | |
253 | debug_assert_eq!( | |
254 | substs.non_erasable_generics().next(), | |
255 | Some(GenericArgKind::Type(ty)) | |
256 | ); | |
257 | symbols.push((ExportedSymbol::DropGlue(ty), SymbolExportLevel::Rust)); | |
258 | } | |
259 | _ => { | |
260 | // Any other symbols don't qualify for sharing | |
83c7162d XL |
261 | } |
262 | } | |
263 | } | |
264 | } | |
265 | ||
0531ce1d | 266 | // Sort so we get a stable incr. comp. hash. |
dfeec247 | 267 | symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx)); |
2c00a5a8 | 268 | |
ba9703b0 | 269 | tcx.arena.alloc_from_iter(symbols) |
ea8adc8c | 270 | } |
476ff2be | 271 | |
416331ca XL |
272 | fn upstream_monomorphizations_provider( |
273 | tcx: TyCtxt<'_>, | |
17df50a5 | 274 | (): (), |
f9f354fc | 275 | ) -> DefIdMap<FxHashMap<SubstsRef<'_>, CrateNum>> { |
136023e0 | 276 | let cnums = tcx.crates(()); |
83c7162d | 277 | |
a1dfa0c6 | 278 | let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default(); |
83c7162d XL |
279 | |
280 | let cnum_stable_ids: IndexVec<CrateNum, Fingerprint> = { | |
dfeec247 | 281 | let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, cnums.len() + 1); |
83c7162d XL |
282 | |
283 | for &cnum in cnums.iter() { | |
dfeec247 XL |
284 | cnum_stable_ids[cnum] = |
285 | tcx.def_path_hash(DefId { krate: cnum, index: CRATE_DEF_INDEX }).0; | |
83c7162d XL |
286 | } |
287 | ||
288 | cnum_stable_ids | |
289 | }; | |
290 | ||
dfeec247 XL |
291 | let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn(); |
292 | ||
83c7162d | 293 | for &cnum in cnums.iter() { |
e74abb32 | 294 | for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() { |
dfeec247 XL |
295 | let (def_id, substs) = match *exported_symbol { |
296 | ExportedSymbol::Generic(def_id, substs) => (def_id, substs), | |
297 | ExportedSymbol::DropGlue(ty) => { | |
298 | if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id { | |
299 | (drop_in_place_fn_def_id, tcx.intern_substs(&[ty.into()])) | |
300 | } else { | |
301 | // `drop_in_place` in place does not exist, don't try | |
302 | // to use it. | |
303 | continue; | |
83c7162d | 304 | } |
dfeec247 XL |
305 | } |
306 | ExportedSymbol::NonGeneric(..) | ExportedSymbol::NoDefId(..) => { | |
307 | // These are no monomorphizations | |
308 | continue; | |
309 | } | |
310 | }; | |
311 | ||
312 | let substs_map = instances.entry(def_id).or_default(); | |
313 | ||
314 | match substs_map.entry(substs) { | |
315 | Occupied(mut e) => { | |
316 | // If there are multiple monomorphizations available, | |
317 | // we select one deterministically. | |
318 | let other_cnum = *e.get(); | |
319 | if cnum_stable_ids[other_cnum] > cnum_stable_ids[cnum] { | |
83c7162d XL |
320 | e.insert(cnum); |
321 | } | |
322 | } | |
dfeec247 XL |
323 | Vacant(e) => { |
324 | e.insert(cnum); | |
325 | } | |
83c7162d XL |
326 | } |
327 | } | |
328 | } | |
329 | ||
f9f354fc | 330 | instances |
83c7162d XL |
331 | } |
332 | ||
416331ca XL |
333 | fn upstream_monomorphizations_for_provider( |
334 | tcx: TyCtxt<'_>, | |
dc9dc135 | 335 | def_id: DefId, |
416331ca | 336 | ) -> Option<&FxHashMap<SubstsRef<'_>, CrateNum>> { |
83c7162d | 337 | debug_assert!(!def_id.is_local()); |
17df50a5 | 338 | tcx.upstream_monomorphizations(()).get(&def_id) |
83c7162d XL |
339 | } |
340 | ||
dfeec247 XL |
341 | fn upstream_drop_glue_for_provider<'tcx>( |
342 | tcx: TyCtxt<'tcx>, | |
343 | substs: SubstsRef<'tcx>, | |
344 | ) -> Option<CrateNum> { | |
345 | if let Some(def_id) = tcx.lang_items().drop_in_place_fn() { | |
346 | tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned()) | |
347 | } else { | |
348 | None | |
349 | } | |
350 | } | |
351 | ||
17df50a5 XL |
352 | fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { |
353 | !tcx.reachable_set(()).contains(&def_id) | |
83c7162d XL |
354 | } |
355 | ||
f035d41b | 356 | pub fn provide(providers: &mut Providers) { |
0531ce1d | 357 | providers.reachable_non_generics = reachable_non_generics_provider; |
83c7162d | 358 | providers.is_reachable_non_generic = is_reachable_non_generic_provider_local; |
0531ce1d | 359 | providers.exported_symbols = exported_symbols_provider_local; |
83c7162d XL |
360 | providers.upstream_monomorphizations = upstream_monomorphizations_provider; |
361 | providers.is_unreachable_local_definition = is_unreachable_local_definition_provider; | |
dfeec247 | 362 | providers.upstream_drop_glue_for = upstream_drop_glue_for_provider; |
17df50a5 | 363 | providers.wasm_import_module_map = wasm_import_module_map; |
0531ce1d | 364 | } |
476ff2be | 365 | |
f035d41b | 366 | pub fn provide_extern(providers: &mut Providers) { |
83c7162d XL |
367 | providers.is_reachable_non_generic = is_reachable_non_generic_provider_extern; |
368 | providers.upstream_monomorphizations_for = upstream_monomorphizations_for_provider; | |
476ff2be SL |
369 | } |
370 | ||
dc9dc135 | 371 | fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel { |
abe05a73 XL |
372 | // We export anything that's not mangled at the "C" layer as it probably has |
373 | // to do with ABI concerns. We do not, however, apply such treatment to | |
374 | // special symbols in the standard library for various plumbing between | |
375 | // core/std/allocators/etc. For example symbols used to hook up allocation | |
376 | // are not considered for export | |
94b46f34 XL |
377 | let codegen_fn_attrs = tcx.codegen_fn_attrs(sym_def_id); |
378 | let is_extern = codegen_fn_attrs.contains_extern_indicator(); | |
379 | let std_internal = | |
380 | codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); | |
0531ce1d | 381 | |
abe05a73 | 382 | if is_extern && !std_internal { |
29967ef6 | 383 | let target = &tcx.sess.target.llvm_target; |
e74abb32 | 384 | // WebAssembly cannot export data symbols, so reduce their export level |
dfeec247 XL |
385 | if target.contains("emscripten") { |
386 | if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) = | |
387 | tcx.hir().get_if_local(sym_def_id) | |
388 | { | |
a1dfa0c6 XL |
389 | return SymbolExportLevel::Rust; |
390 | } | |
391 | } | |
392 | ||
476ff2be | 393 | SymbolExportLevel::C |
476ff2be | 394 | } else { |
ea8adc8c | 395 | SymbolExportLevel::Rust |
476ff2be SL |
396 | } |
397 | } | |
dfeec247 XL |
398 | |
399 | /// This is the symbol name of the given instance instantiated in a specific crate. | |
400 | pub fn symbol_name_for_instance_in_crate<'tcx>( | |
401 | tcx: TyCtxt<'tcx>, | |
402 | symbol: ExportedSymbol<'tcx>, | |
403 | instantiating_crate: CrateNum, | |
404 | ) -> String { | |
405 | // If this is something instantiated in the local crate then we might | |
406 | // already have cached the name as a query result. | |
407 | if instantiating_crate == LOCAL_CRATE { | |
408 | return symbol.symbol_name_for_local_instance(tcx).to_string(); | |
409 | } | |
410 | ||
411 | // This is something instantiated in an upstream crate, so we have to use | |
412 | // the slower (because uncached) version of computing the symbol name. | |
413 | match symbol { | |
ba9703b0 XL |
414 | ExportedSymbol::NonGeneric(def_id) => { |
415 | rustc_symbol_mangling::symbol_name_for_instance_in_crate( | |
416 | tcx, | |
417 | Instance::mono(tcx, def_id), | |
418 | instantiating_crate, | |
419 | ) | |
420 | } | |
421 | ExportedSymbol::Generic(def_id, substs) => { | |
422 | rustc_symbol_mangling::symbol_name_for_instance_in_crate( | |
423 | tcx, | |
424 | Instance::new(def_id, substs), | |
425 | instantiating_crate, | |
426 | ) | |
427 | } | |
428 | ExportedSymbol::DropGlue(ty) => rustc_symbol_mangling::symbol_name_for_instance_in_crate( | |
dfeec247 XL |
429 | tcx, |
430 | Instance::resolve_drop_in_place(tcx, ty), | |
431 | instantiating_crate, | |
432 | ), | |
433 | ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(), | |
434 | } | |
435 | } | |
17df50a5 XL |
436 | |
437 | fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, String> { | |
438 | // Build up a map from DefId to a `NativeLib` structure, where | |
439 | // `NativeLib` internally contains information about | |
440 | // `#[link(wasm_import_module = "...")]` for example. | |
441 | let native_libs = tcx.native_libraries(cnum); | |
442 | ||
443 | let def_id_to_native_lib = native_libs | |
444 | .iter() | |
445 | .filter_map(|lib| lib.foreign_module.map(|id| (id, lib))) | |
446 | .collect::<FxHashMap<_, _>>(); | |
447 | ||
448 | let mut ret = FxHashMap::default(); | |
449 | for (def_id, lib) in tcx.foreign_modules(cnum).iter() { | |
450 | let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module); | |
451 | let module = match module { | |
452 | Some(s) => s, | |
453 | None => continue, | |
454 | }; | |
455 | ret.extend(lib.foreign_items.iter().map(|id| { | |
456 | assert_eq!(id.krate, cnum); | |
457 | (*id, module.to_string()) | |
458 | })); | |
459 | } | |
460 | ||
461 | ret | |
462 | } |