Skip to content

Commit 3462b58

Browse files
committed
Add support for parsing #[link_ordinal] attribute.
1 parent e70ffed commit 3462b58

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/librustc/hir/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2669,6 +2669,11 @@ pub struct CodegenFnAttrs {
26692669
/// probably isn't set when this is set, this is for foreign items while
26702670
/// `#[export_name]` is for Rust-defined functions.
26712671
pub link_name: Option<Symbol>,
2672+
/// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
2673+
/// imported function has in the dynamic library. Note that this must not
2674+
/// be set when `link_name` is set. This is for foreign items with the
2675+
/// "raw-dylib" kind.
2676+
pub link_ordinal: Option<usize>,
26722677
/// The `#[target_feature(enable = "...")]` attribute and the enabled
26732678
/// features (only enabled features are supported right now).
26742679
pub target_features: Vec<Symbol>,
@@ -2728,6 +2733,7 @@ impl CodegenFnAttrs {
27282733
optimize: OptimizeAttr::None,
27292734
export_name: None,
27302735
link_name: None,
2736+
link_ordinal: None,
27312737
target_features: vec![],
27322738
linkage: None,
27332739
link_section: None,

src/librustc_typeck/collect.rs

+38
Original file line numberDiff line numberDiff line change
@@ -2641,6 +2641,35 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
26412641
}
26422642
} else if attr.check_name(sym::link_name) {
26432643
codegen_fn_attrs.link_name = attr.value_str();
2644+
} else if attr.check_name(sym::link_ordinal) {
2645+
use syntax::ast::{Lit, LitIntType, LitKind};
2646+
let meta_item_list = attr.meta_item_list();
2647+
let sole_meta_lit = if let Some(meta_item_list) = &meta_item_list {
2648+
if meta_item_list.len() == 1 {
2649+
meta_item_list.get(0).and_then(|item| item.literal())
2650+
} else {
2651+
None
2652+
}
2653+
} else {
2654+
None
2655+
};
2656+
if let Some(Lit { node: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
2657+
sole_meta_lit
2658+
{
2659+
if *ordinal <= std::usize::MAX as u128 {
2660+
codegen_fn_attrs.link_ordinal = Some(*ordinal as usize);
2661+
} else {
2662+
let msg = format!(
2663+
"too large ordinal value in link_ordinal \
2664+
value: `{}`",
2665+
&ordinal
2666+
);
2667+
tcx.sess.span_err(attr.span, &msg);
2668+
}
2669+
} else {
2670+
let msg = "illegal ordinal format in link_ordinal";
2671+
tcx.sess.span_err(attr.span, &msg);
2672+
}
26442673
}
26452674
}
26462675

@@ -2742,6 +2771,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
27422771
codegen_fn_attrs.export_name = Some(name);
27432772
codegen_fn_attrs.link_name = Some(name);
27442773
}
2774+
if codegen_fn_attrs.link_name.is_some() && codegen_fn_attrs.link_ordinal.is_some() {
2775+
if let Some(span) = inline_span {
2776+
tcx.sess.span_err(
2777+
span,
2778+
"cannot use `#[link_name]` with \
2779+
`#[link_ordinal]`",
2780+
);
2781+
}
2782+
}
27452783

27462784
// Internal symbols to the standard library all have no_mangle semantics in
27472785
// that they have defined symbol names present in the function name. This

0 commit comments

Comments
 (0)