@@ -2603,6 +2603,35 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2603
2603
}
2604
2604
} else if attr. check_name ( sym:: link_name) {
2605
2605
codegen_fn_attrs. link_name = attr. value_str ( ) ;
2606
+ } else if attr. check_name ( sym:: link_ordinal) {
2607
+ use syntax:: ast:: { Lit , LitIntType , LitKind } ;
2608
+ let meta_item_list = attr. meta_item_list ( ) ;
2609
+ let sole_meta_lit = if let Some ( meta_item_list) = & meta_item_list {
2610
+ if meta_item_list. len ( ) == 1 {
2611
+ meta_item_list. get ( 0 ) . and_then ( |item| item. literal ( ) )
2612
+ } else {
2613
+ None
2614
+ }
2615
+ } else {
2616
+ None
2617
+ } ;
2618
+ if let Some ( Lit { node : LitKind :: Int ( ordinal, LitIntType :: Unsuffixed ) , .. } ) =
2619
+ sole_meta_lit
2620
+ {
2621
+ if * ordinal <= std:: usize:: MAX as u128 {
2622
+ codegen_fn_attrs. link_ordinal = Some ( * ordinal as usize ) ;
2623
+ } else {
2624
+ let msg = format ! (
2625
+ "too large ordinal value in link_ordinal \
2626
+ value: `{}`",
2627
+ & ordinal
2628
+ ) ;
2629
+ tcx. sess . span_err ( attr. span , & msg) ;
2630
+ }
2631
+ } else {
2632
+ let msg = "illegal ordinal format in link_ordinal" ;
2633
+ tcx. sess . span_err ( attr. span , & msg) ;
2634
+ }
2606
2635
}
2607
2636
}
2608
2637
@@ -2704,6 +2733,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2704
2733
codegen_fn_attrs. export_name = Some ( name) ;
2705
2734
codegen_fn_attrs. link_name = Some ( name) ;
2706
2735
}
2736
+ if codegen_fn_attrs. link_name . is_some ( ) && codegen_fn_attrs. link_ordinal . is_some ( ) {
2737
+ if let Some ( span) = inline_span {
2738
+ tcx. sess . span_err (
2739
+ span,
2740
+ "cannot use `#[link_name]` with \
2741
+ `#[link_ordinal]`",
2742
+ ) ;
2743
+ }
2744
+ }
2707
2745
2708
2746
// Internal symbols to the standard library all have no_mangle semantics in
2709
2747
// that they have defined symbol names present in the function name. This
0 commit comments