@@ -5,7 +5,7 @@ use rustc_errors::struct_span_err;
5
5
use rustc_hir as hir;
6
6
use rustc_hir:: def:: DefKind ;
7
7
use rustc_middle:: ty:: { List , ParamEnv , ParamEnvAnd , Ty , TyCtxt } ;
8
- use rustc_session:: cstore:: { DllCallingConvention , DllImport , NativeLib } ;
8
+ use rustc_session:: cstore:: { DllCallingConvention , DllImport , NativeLib , PeImportNameType } ;
9
9
use rustc_session:: parse:: feature_err;
10
10
use rustc_session:: utils:: NativeLibKind ;
11
11
use rustc_session:: Session ;
@@ -61,6 +61,7 @@ impl<'tcx> Collector<'tcx> {
61
61
let mut modifiers = None ;
62
62
let mut cfg = None ;
63
63
let mut wasm_import_module = None ;
64
+ let mut import_name_type = None ;
64
65
for item in items. iter ( ) {
65
66
match item. name_or_empty ( ) {
66
67
sym:: name => {
@@ -199,9 +200,51 @@ impl<'tcx> Collector<'tcx> {
199
200
} ;
200
201
wasm_import_module = Some ( ( link_wasm_import_module, item. span ( ) ) ) ;
201
202
}
203
+ sym:: import_name_type => {
204
+ if import_name_type. is_some ( ) {
205
+ let msg = "multiple `import_name_type` arguments in a single `#[link]` attribute" ;
206
+ sess. span_err ( item. span ( ) , msg) ;
207
+ continue ;
208
+ }
209
+ let Some ( link_import_name_type) = item. value_str ( ) else {
210
+ let msg = "import name type must be of the form `import_name_type = \" string\" `" ;
211
+ sess. span_err ( item. span ( ) , msg) ;
212
+ continue ;
213
+ } ;
214
+ if self . tcx . sess . target . arch != "x86" {
215
+ let msg = "import name type is only supported on x86" ;
216
+ sess. span_err ( item. span ( ) , msg) ;
217
+ continue ;
218
+ }
219
+
220
+ let link_import_name_type = match link_import_name_type. as_str ( ) {
221
+ "decorated" => PeImportNameType :: Decorated ,
222
+ "noprefix" => PeImportNameType :: NoPrefix ,
223
+ "undecorated" => PeImportNameType :: Undecorated ,
224
+ import_name_type => {
225
+ let msg = format ! (
226
+ "unknown import name type `{import_name_type}`, expected one of: \
227
+ decorated, noprefix, undecorated"
228
+ ) ;
229
+ sess. span_err ( item. span ( ) , msg) ;
230
+ continue ;
231
+ }
232
+ } ;
233
+ if !features. raw_dylib {
234
+ let span = item. name_value_literal_span ( ) . unwrap ( ) ;
235
+ feature_err (
236
+ & sess. parse_sess ,
237
+ sym:: raw_dylib,
238
+ span,
239
+ "import name type is unstable" ,
240
+ )
241
+ . emit ( ) ;
242
+ }
243
+ import_name_type = Some ( ( link_import_name_type, item. span ( ) ) ) ;
244
+ }
202
245
_ => {
203
246
let msg = "unexpected `#[link]` argument, expected one of: \
204
- name, kind, modifiers, cfg, wasm_import_module";
247
+ name, kind, modifiers, cfg, wasm_import_module, import_name_type ";
205
248
sess. span_err ( item. span ( ) , msg) ;
206
249
}
207
250
}
@@ -315,6 +358,14 @@ impl<'tcx> Collector<'tcx> {
315
358
. emit ( ) ;
316
359
}
317
360
361
+ // Do this outside of the loop so that `import_name_type` can be specified before `kind`.
362
+ if let Some ( ( _, span) ) = import_name_type {
363
+ if kind != Some ( NativeLibKind :: RawDylib ) {
364
+ let msg = "import name type can only be used with link kind `raw-dylib`" ;
365
+ sess. span_err ( span, msg) ;
366
+ }
367
+ }
368
+
318
369
let dll_imports = match kind {
319
370
Some ( NativeLibKind :: RawDylib ) => {
320
371
if let Some ( ( name, span) ) = name && name. as_str ( ) . contains ( '\0' ) {
@@ -325,7 +376,13 @@ impl<'tcx> Collector<'tcx> {
325
376
}
326
377
foreign_mod_items
327
378
. iter ( )
328
- . map ( |child_item| self . build_dll_import ( abi, child_item) )
379
+ . map ( |child_item| {
380
+ self . build_dll_import (
381
+ abi,
382
+ import_name_type. map ( |( import_name_type, _) | import_name_type) ,
383
+ child_item,
384
+ )
385
+ } )
329
386
. collect ( )
330
387
}
331
388
_ => {
@@ -486,7 +543,12 @@ impl<'tcx> Collector<'tcx> {
486
543
. sum ( )
487
544
}
488
545
489
- fn build_dll_import ( & self , abi : Abi , item : & hir:: ForeignItemRef ) -> DllImport {
546
+ fn build_dll_import (
547
+ & self ,
548
+ abi : Abi ,
549
+ import_name_type : Option < PeImportNameType > ,
550
+ item : & hir:: ForeignItemRef ,
551
+ ) -> DllImport {
490
552
let calling_convention = if self . tcx . sess . target . arch == "x86" {
491
553
match abi {
492
554
Abi :: C { .. } | Abi :: Cdecl { .. } => DllCallingConvention :: C ,
@@ -518,11 +580,18 @@ impl<'tcx> Collector<'tcx> {
518
580
}
519
581
} ;
520
582
583
+ let import_name_type = self
584
+ . tcx
585
+ . codegen_fn_attrs ( item. id . def_id )
586
+ . link_ordinal
587
+ . map_or ( import_name_type, |ord| Some ( PeImportNameType :: Ordinal ( ord) ) ) ;
588
+
521
589
DllImport {
522
590
name : item. ident . name ,
523
- ordinal : self . tcx . codegen_fn_attrs ( item . id . def_id ) . link_ordinal ,
591
+ import_name_type ,
524
592
calling_convention,
525
593
span : item. span ,
594
+ is_fn : self . tcx . def_kind ( item. id . def_id ) . is_fn_like ( ) ,
526
595
}
527
596
}
528
597
}
0 commit comments