]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_metadata/src/native_libs.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / compiler / rustc_metadata / src / native_libs.rs
CommitLineData
923072b8 1use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
74b04a01 2use rustc_attr as attr;
dfeec247 3use rustc_data_structures::fx::FxHashSet;
dfeec247 4use rustc_hir as hir;
04454e1e 5use rustc_hir::def::DefKind;
136023e0 6use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
f2b60f7d
FG
7use rustc_session::config::CrateType;
8use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib, PeImportNameType};
ba9703b0 9use rustc_session::parse::feature_err;
f2b60f7d 10use rustc_session::search_paths::PathKind;
f9f354fc 11use rustc_session::utils::NativeLibKind;
ba9703b0 12use rustc_session::Session;
923072b8 13use rustc_span::symbol::{sym, Symbol};
83c7162d 14use rustc_target::spec::abi::Abi;
60c5eb7d 15
f2b60f7d
FG
16use crate::errors::{
17 AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, EmptyRenamingTarget,
18 FrameworkOnlyWindows, ImportNameTypeForm, ImportNameTypeRaw, ImportNameTypeX86,
19 IncompatibleWasmLink, InvalidLinkModifier, LibFrameworkApple, LinkCfgForm,
20 LinkCfgSinglePredicate, LinkFrameworkApple, LinkKindForm, LinkModifiersForm, LinkNameForm,
21 LinkOrdinalRawDylib, LinkRequiresName, MissingNativeLibrary, MultipleCfgs,
22 MultipleImportNameType, MultipleKindsInLink, MultipleLinkModifiers, MultipleModifiers,
23 MultipleNamesInLink, MultipleRenamings, MultipleWasmImport, NoLinkModOverride, RawDylibNoNul,
24 RenamingNoLink, UnexpectedLinkArg, UnknownImportNameType, UnknownLinkKind, UnknownLinkModifier,
25 UnsupportedAbi, UnsupportedAbiI686, WasmImportForm, WholeArchiveNeedsStatic,
26};
27
28use std::path::PathBuf;
29
30pub fn find_native_static_library(
31 name: &str,
487cf647 32 verbatim: bool,
f2b60f7d
FG
33 search_paths: &[PathBuf],
34 sess: &Session,
35) -> PathBuf {
487cf647 36 let formats = if verbatim {
2b03887a 37 vec![("".into(), "".into())]
f2b60f7d 38 } else {
2b03887a
FG
39 let os = (sess.target.staticlib_prefix.clone(), sess.target.staticlib_suffix.clone());
40 // On Windows, static libraries sometimes show up as libfoo.a and other
41 // times show up as foo.lib
42 let unix = ("lib".into(), ".a".into());
43 if os == unix { vec![os] } else { vec![os, unix] }
f2b60f7d 44 };
f2b60f7d
FG
45
46 for path in search_paths {
2b03887a 47 for (prefix, suffix) in &formats {
9c376795 48 let test = path.join(format!("{prefix}{name}{suffix}"));
f2b60f7d
FG
49 if test.exists() {
50 return test;
51 }
52 }
53 }
2b03887a 54
487cf647 55 sess.emit_fatal(MissingNativeLibrary::new(name, verbatim));
f2b60f7d
FG
56}
57
58fn find_bundled_library(
59 name: Option<Symbol>,
60 verbatim: Option<bool>,
61 kind: NativeLibKind,
62 sess: &Session,
63) -> Option<Symbol> {
64 if sess.opts.unstable_opts.packed_bundled_libs &&
65 sess.crate_types().iter().any(|ct| ct == &CrateType::Rlib || ct == &CrateType::Staticlib) &&
66 let NativeLibKind::Static { bundle: Some(true) | None, .. } = kind {
67 find_native_static_library(
68 name.unwrap().as_str(),
487cf647 69 verbatim.unwrap_or(false),
f2b60f7d
FG
70 &sess.target_filesearch(PathKind::Native).search_path_dirs(),
71 sess,
72 ).file_name().and_then(|s| s.to_str()).map(Symbol::intern)
73 } else {
74 None
75 }
76}
77
923072b8 78pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
dfeec247 79 let mut collector = Collector { tcx, libs: Vec::new() };
04454e1e
FG
80 for id in tcx.hir().items() {
81 collector.process_item(id);
82 }
ea8adc8c 83 collector.process_command_line();
ba9703b0 84 collector.libs
ea8adc8c
XL
85}
86
923072b8 87pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
ea8adc8c 88 match lib.cfg {
5e7ed085 89 Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, CRATE_NODE_ID, None),
ea8adc8c
XL
90 None => true,
91 }
92}
93
dc9dc135
XL
94struct Collector<'tcx> {
95 tcx: TyCtxt<'tcx>,
f9f354fc 96 libs: Vec<NativeLib>,
ea8adc8c
XL
97}
98
04454e1e
FG
99impl<'tcx> Collector<'tcx> {
100 fn process_item(&mut self, id: rustc_hir::ItemId) {
2b03887a 101 if !matches!(self.tcx.def_kind(id.owner_id), DefKind::ForeignMod) {
04454e1e
FG
102 return;
103 }
104
105 let it = self.tcx.hir().item(id);
5e7ed085
FG
106 let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else {
107 return;
ea8adc8c
XL
108 };
109
fc512014 110 if abi == Abi::Rust || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
dfeec247 111 return;
ea8adc8c
XL
112 }
113
114 // Process all of the #[link(..)]-style arguments
3dfed10e 115 let sess = &self.tcx.sess;
923072b8 116 let features = self.tcx.features();
94222f64 117 for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) {
5e7ed085
FG
118 let Some(items) = m.meta_item_list() else {
119 continue;
ea8adc8c 120 };
8faf50e0 121
923072b8
FG
122 let mut name = None;
123 let mut kind = None;
124 let mut modifiers = None;
125 let mut cfg = None;
126 let mut wasm_import_module = None;
f2b60f7d 127 let mut import_name_type = None;
8faf50e0 128 for item in items.iter() {
923072b8
FG
129 match item.name_or_empty() {
130 sym::name => {
131 if name.is_some() {
f2b60f7d 132 sess.emit_err(MultipleNamesInLink { span: item.span() });
923072b8 133 continue;
17df50a5 134 }
923072b8 135 let Some(link_name) = item.value_str() else {
f2b60f7d 136 sess.emit_err(LinkNameForm { span: item.span() });
923072b8
FG
137 continue;
138 };
139 let span = item.name_value_literal_span().unwrap();
140 if link_name.is_empty() {
f2b60f7d 141 sess.emit_err(EmptyLinkName { span });
8faf50e0 142 }
923072b8 143 name = Some((link_name, span));
8faf50e0 144 }
923072b8
FG
145 sym::kind => {
146 if kind.is_some() {
f2b60f7d 147 sess.emit_err(MultipleKindsInLink { span: item.span() });
923072b8 148 continue;
8faf50e0 149 }
923072b8 150 let Some(link_kind) = item.value_str() else {
f2b60f7d 151 sess.emit_err(LinkKindForm { span: item.span() });
923072b8 152 continue;
17df50a5
XL
153 };
154
923072b8
FG
155 let span = item.name_value_literal_span().unwrap();
156 let link_kind = match link_kind.as_str() {
157 "static" => NativeLibKind::Static { bundle: None, whole_archive: None },
158 "dylib" => NativeLibKind::Dylib { as_needed: None },
159 "framework" => {
160 if !sess.target.is_like_osx {
f2b60f7d 161 sess.emit_err(LinkFrameworkApple { span });
5e7ed085 162 }
923072b8 163 NativeLibKind::Framework { as_needed: None }
5e7ed085 164 }
923072b8
FG
165 "raw-dylib" => {
166 if !sess.target.is_like_windows {
f2b60f7d
FG
167 sess.emit_err(FrameworkOnlyWindows { span });
168 } else if !features.raw_dylib && sess.target.arch == "x86" {
923072b8
FG
169 feature_err(
170 &sess.parse_sess,
171 sym::raw_dylib,
172 span,
f2b60f7d 173 "link kind `raw-dylib` is unstable on x86",
923072b8
FG
174 )
175 .emit();
5e7ed085 176 }
923072b8 177 NativeLibKind::RawDylib
17df50a5 178 }
923072b8 179 kind => {
f2b60f7d 180 sess.emit_err(UnknownLinkKind { span, kind });
923072b8 181 continue;
5e7ed085 182 }
923072b8
FG
183 };
184 kind = Some(link_kind);
185 }
186 sym::modifiers => {
187 if modifiers.is_some() {
f2b60f7d 188 sess.emit_err(MultipleLinkModifiers { span: item.span() });
923072b8 189 continue;
17df50a5 190 }
923072b8 191 let Some(link_modifiers) = item.value_str() else {
f2b60f7d 192 sess.emit_err(LinkModifiersForm { span: item.span() });
923072b8
FG
193 continue;
194 };
195 modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap()));
17df50a5 196 }
923072b8
FG
197 sym::cfg => {
198 if cfg.is_some() {
f2b60f7d 199 sess.emit_err(MultipleCfgs { span: item.span() });
923072b8
FG
200 continue;
201 }
202 let Some(link_cfg) = item.meta_item_list() else {
f2b60f7d 203 sess.emit_err(LinkCfgForm { span: item.span() });
923072b8
FG
204 continue;
205 };
206 let [NestedMetaItem::MetaItem(link_cfg)] = link_cfg else {
f2b60f7d 207 sess.emit_err(LinkCfgSinglePredicate { span: item.span() });
923072b8
FG
208 continue;
209 };
210 if !features.link_cfg {
211 feature_err(
212 &sess.parse_sess,
213 sym::link_cfg,
214 item.span(),
215 "link cfg is unstable",
216 )
217 .emit();
218 }
219 cfg = Some(link_cfg.clone());
220 }
221 sym::wasm_import_module => {
222 if wasm_import_module.is_some() {
f2b60f7d 223 sess.emit_err(MultipleWasmImport { span: item.span() });
923072b8
FG
224 continue;
225 }
226 let Some(link_wasm_import_module) = item.value_str() else {
f2b60f7d 227 sess.emit_err(WasmImportForm { span: item.span() });
923072b8
FG
228 continue;
229 };
230 wasm_import_module = Some((link_wasm_import_module, item.span()));
231 }
f2b60f7d
FG
232 sym::import_name_type => {
233 if import_name_type.is_some() {
234 sess.emit_err(MultipleImportNameType { span: item.span() });
235 continue;
236 }
237 let Some(link_import_name_type) = item.value_str() else {
238 sess.emit_err(ImportNameTypeForm { span: item.span() });
239 continue;
240 };
241 if self.tcx.sess.target.arch != "x86" {
242 sess.emit_err(ImportNameTypeX86 { span: item.span() });
243 continue;
244 }
245
246 let link_import_name_type = match link_import_name_type.as_str() {
247 "decorated" => PeImportNameType::Decorated,
248 "noprefix" => PeImportNameType::NoPrefix,
249 "undecorated" => PeImportNameType::Undecorated,
250 import_name_type => {
251 sess.emit_err(UnknownImportNameType {
252 span: item.span(),
253 import_name_type,
254 });
255 continue;
256 }
257 };
258 if !features.raw_dylib {
259 let span = item.name_value_literal_span().unwrap();
260 feature_err(
261 &sess.parse_sess,
262 sym::raw_dylib,
263 span,
264 "import name type is unstable",
265 )
266 .emit();
267 }
268 import_name_type = Some((link_import_name_type, item.span()));
269 }
923072b8 270 _ => {
f2b60f7d 271 sess.emit_err(UnexpectedLinkArg { span: item.span() });
5e7ed085 272 }
17df50a5
XL
273 }
274 }
275
923072b8
FG
276 // Do this outside the above loop so we don't depend on modifiers coming after kinds
277 let mut verbatim = None;
278 if let Some((modifiers, span)) = modifiers {
279 for modifier in modifiers.as_str().split(',') {
280 let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
281 Some(m) => (m, modifier.starts_with('+')),
282 None => {
f2b60f7d 283 sess.emit_err(InvalidLinkModifier { span });
923072b8
FG
284 continue;
285 }
286 };
287
288 macro report_unstable_modifier($feature: ident) {
289 if !features.$feature {
290 feature_err(
291 &sess.parse_sess,
292 sym::$feature,
293 span,
294 &format!("linking modifier `{modifier}` is unstable"),
295 )
296 .emit();
297 }
298 }
299 let assign_modifier = |dst: &mut Option<bool>| {
300 if dst.is_some() {
f2b60f7d 301 sess.emit_err(MultipleModifiers { span, modifier });
923072b8
FG
302 } else {
303 *dst = Some(value);
304 }
305 };
306 match (modifier, &mut kind) {
307 ("bundle", Some(NativeLibKind::Static { bundle, .. })) => {
308 assign_modifier(bundle)
309 }
310 ("bundle", _) => {
f2b60f7d 311 sess.emit_err(BundleNeedsStatic { span });
923072b8
FG
312 }
313
487cf647 314 ("verbatim", _) => assign_modifier(&mut verbatim),
923072b8
FG
315
316 ("whole-archive", Some(NativeLibKind::Static { whole_archive, .. })) => {
317 assign_modifier(whole_archive)
318 }
319 ("whole-archive", _) => {
f2b60f7d 320 sess.emit_err(WholeArchiveNeedsStatic { span });
923072b8
FG
321 }
322
323 ("as-needed", Some(NativeLibKind::Dylib { as_needed }))
324 | ("as-needed", Some(NativeLibKind::Framework { as_needed })) => {
325 report_unstable_modifier!(native_link_modifiers_as_needed);
326 assign_modifier(as_needed)
327 }
328 ("as-needed", _) => {
f2b60f7d 329 sess.emit_err(AsNeededCompatibility { span });
923072b8
FG
330 }
331
332 _ => {
f2b60f7d 333 sess.emit_err(UnknownLinkModifier { span, modifier });
923072b8
FG
334 }
335 }
336 }
5e7ed085
FG
337 }
338
923072b8
FG
339 if let Some((_, span)) = wasm_import_module {
340 if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
f2b60f7d 341 sess.emit_err(IncompatibleWasmLink { span });
923072b8
FG
342 }
343 } else if name.is_none() {
f2b60f7d
FG
344 sess.emit_err(LinkRequiresName { span: m.span });
345 }
346
347 // Do this outside of the loop so that `import_name_type` can be specified before `kind`.
348 if let Some((_, span)) = import_name_type {
349 if kind != Some(NativeLibKind::RawDylib) {
350 sess.emit_err(ImportNameTypeRaw { span });
351 }
8faf50e0 352 }
17df50a5 353
923072b8
FG
354 let dll_imports = match kind {
355 Some(NativeLibKind::RawDylib) => {
356 if let Some((name, span)) = name && name.as_str().contains('\0') {
f2b60f7d 357 sess.emit_err(RawDylibNoNul { span });
923072b8 358 }
17df50a5
XL
359 foreign_mod_items
360 .iter()
f2b60f7d
FG
361 .map(|child_item| {
362 self.build_dll_import(
363 abi,
364 import_name_type.map(|(import_name_type, _)| import_name_type),
365 child_item,
366 )
367 })
923072b8 368 .collect()
ea8adc8c 369 }
f2b60f7d
FG
370 _ => {
371 for child_item in foreign_mod_items {
2b03887a 372 if self.tcx.def_kind(child_item.id.owner_id).has_codegen_attrs()
f2b60f7d
FG
373 && self
374 .tcx
2b03887a 375 .codegen_fn_attrs(child_item.id.owner_id)
f2b60f7d
FG
376 .link_ordinal
377 .is_some()
378 {
379 let link_ordinal_attr = self
380 .tcx
381 .hir()
2b03887a 382 .attrs(child_item.id.owner_id.into())
f2b60f7d
FG
383 .iter()
384 .find(|a| a.has_name(sym::link_ordinal))
385 .unwrap();
386 sess.emit_err(LinkOrdinalRawDylib { span: link_ordinal_attr.span });
387 }
388 }
389
390 Vec::new()
391 }
17df50a5 392 };
f2b60f7d
FG
393
394 let name = name.map(|(name, _)| name);
395 let kind = kind.unwrap_or(NativeLibKind::Unspecified);
396 let filename = find_bundled_library(name, verbatim, kind, sess);
923072b8 397 self.libs.push(NativeLib {
f2b60f7d
FG
398 name,
399 filename,
400 kind,
923072b8 401 cfg,
2b03887a 402 foreign_module: Some(it.owner_id.to_def_id()),
923072b8
FG
403 wasm_import_module: wasm_import_module.map(|(name, _)| name),
404 verbatim,
405 dll_imports,
406 });
e74abb32 407 }
ea8adc8c
XL
408 }
409
410 // Process libs passed on the command line
411 fn process_command_line(&mut self) {
412 // First, check for errors
0bf4aa26 413 let mut renames = FxHashSet::default();
17df50a5 414 for lib in &self.tcx.sess.opts.libs {
923072b8
FG
415 if let NativeLibKind::Framework { .. } = lib.kind && !self.tcx.sess.target.is_like_osx {
416 // Cannot check this when parsing options because the target is not yet available.
f2b60f7d 417 self.tcx.sess.emit_err(LibFrameworkApple);
923072b8 418 }
17df50a5 419 if let Some(ref new_name) = lib.new_name {
dfeec247
XL
420 let any_duplicate = self
421 .libs
8faf50e0
XL
422 .iter()
423 .filter_map(|lib| lib.name.as_ref())
3c0e092e 424 .any(|n| n.as_str() == lib.name);
ea8adc8c 425 if new_name.is_empty() {
f2b60f7d 426 self.tcx.sess.emit_err(EmptyRenamingTarget { lib_name: &lib.name });
8faf50e0 427 } else if !any_duplicate {
f2b60f7d 428 self.tcx.sess.emit_err(RenamingNoLink { lib_name: &lib.name });
17df50a5 429 } else if !renames.insert(&lib.name) {
f2b60f7d 430 self.tcx.sess.emit_err(MultipleRenamings { lib_name: &lib.name });
ea8adc8c
XL
431 }
432 }
433 }
434
b7449926 435 // Update kind and, optionally, the name of all native libraries
9c376795 436 // (there may be more than one) with the specified name. If any
532ac7d7
XL
437 // library is mentioned more than once, keep the latest mention
438 // of it, so that any possible dependent libraries appear before
9c376795 439 // it. (This ensures that the linker is able to see symbols from
532ac7d7
XL
440 // all possible dependent libraries before linking in the library
441 // in question.)
17df50a5 442 for passed_lib in &self.tcx.sess.opts.libs {
532ac7d7
XL
443 // If we've already added any native libraries with the same
444 // name, they will be pulled out into `existing`, so that we
445 // can move them to the end of the list below.
dfeec247
XL
446 let mut existing = self
447 .libs
448 .drain_filter(|lib| {
449 if let Some(lib_name) = lib.name {
17df50a5 450 if lib_name.as_str() == passed_lib.name {
5e7ed085
FG
451 // FIXME: This whole logic is questionable, whether modifiers are
452 // involved or not, library reordering and kind overriding without
453 // explicit `:rename` in particular.
454 if lib.has_modifiers() || passed_lib.has_modifiers() {
04454e1e 455 match lib.foreign_module {
f2b60f7d
FG
456 Some(def_id) => self.tcx.sess.emit_err(NoLinkModOverride {
457 span: Some(self.tcx.def_span(def_id)),
458 }),
459 None => {
460 self.tcx.sess.emit_err(NoLinkModOverride { span: None })
461 }
04454e1e 462 };
5e7ed085 463 }
17df50a5
XL
464 if passed_lib.kind != NativeLibKind::Unspecified {
465 lib.kind = passed_lib.kind;
dfeec247 466 }
17df50a5 467 if let Some(new_name) = &passed_lib.new_name {
dfeec247
XL
468 lib.name = Some(Symbol::intern(new_name));
469 }
17df50a5 470 lib.verbatim = passed_lib.verbatim;
dfeec247 471 return true;
532ac7d7 472 }
ea8adc8c 473 }
dfeec247
XL
474 false
475 })
476 .collect::<Vec<_>>();
532ac7d7 477 if existing.is_empty() {
ea8adc8c 478 // Add if not found
c295e0f8 479 let new_name: Option<&str> = passed_lib.new_name.as_deref();
f2b60f7d
FG
480 let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name)));
481 let sess = self.tcx.sess;
482 let filename =
483 find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, sess);
923072b8 484 self.libs.push(NativeLib {
f2b60f7d
FG
485 name,
486 filename,
17df50a5 487 kind: passed_lib.kind,
ea8adc8c 488 cfg: None,
0531ce1d 489 foreign_module: None,
8faf50e0 490 wasm_import_module: None,
17df50a5
XL
491 verbatim: passed_lib.verbatim,
492 dll_imports: Vec::new(),
923072b8 493 });
532ac7d7
XL
494 } else {
495 // Move all existing libraries with the same name to the
496 // end of the command line.
497 self.libs.append(&mut existing);
ea8adc8c
XL
498 }
499 }
500 }
136023e0 501
c295e0f8 502 fn i686_arg_list_size(&self, item: &hir::ForeignItemRef) -> usize {
136023e0
XL
503 let argument_types: &List<Ty<'_>> = self.tcx.erase_late_bound_regions(
504 self.tcx
2b03887a 505 .type_of(item.id.owner_id)
136023e0
XL
506 .fn_sig(self.tcx)
507 .inputs()
508 .map_bound(|slice| self.tcx.mk_type_list(slice.iter())),
509 );
510
511 argument_types
512 .iter()
513 .map(|ty| {
514 let layout = self
515 .tcx
516 .layout_of(ParamEnvAnd { param_env: ParamEnv::empty(), value: ty })
517 .expect("layout")
518 .layout;
519 // In both stdcall and fastcall, we always round up the argument size to the
520 // nearest multiple of 4 bytes.
5e7ed085 521 (layout.size().bytes_usize() + 3) & !3
136023e0
XL
522 })
523 .sum()
524 }
525
f2b60f7d
FG
526 fn build_dll_import(
527 &self,
528 abi: Abi,
529 import_name_type: Option<PeImportNameType>,
530 item: &hir::ForeignItemRef,
531 ) -> DllImport {
136023e0
XL
532 let calling_convention = if self.tcx.sess.target.arch == "x86" {
533 match abi {
5099ac24 534 Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C,
136023e0
XL
535 Abi::Stdcall { .. } | Abi::System { .. } => {
536 DllCallingConvention::Stdcall(self.i686_arg_list_size(item))
537 }
5099ac24
FG
538 Abi::Fastcall { .. } => {
539 DllCallingConvention::Fastcall(self.i686_arg_list_size(item))
540 }
064997fb
FG
541 Abi::Vectorcall { .. } => {
542 DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
543 }
136023e0 544 _ => {
f2b60f7d 545 self.tcx.sess.emit_fatal(UnsupportedAbiI686 { span: item.span });
136023e0
XL
546 }
547 }
548 } else {
549 match abi {
5099ac24 550 Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C,
136023e0 551 _ => {
f2b60f7d 552 self.tcx.sess.emit_fatal(UnsupportedAbi { span: item.span });
136023e0
XL
553 }
554 }
555 };
c295e0f8 556
2b03887a 557 let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.owner_id);
f2b60f7d
FG
558 let import_name_type = codegen_fn_attrs
559 .link_ordinal
560 .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
561
c295e0f8 562 DllImport {
f2b60f7d
FG
563 name: codegen_fn_attrs.link_name.unwrap_or(item.ident.name),
564 import_name_type,
c295e0f8
XL
565 calling_convention,
566 span: item.span,
2b03887a 567 is_fn: self.tcx.def_kind(item.id.owner_id).is_fn_like(),
c295e0f8 568 }
136023e0 569 }
ea8adc8c 570}