Skip to content

Commit bf4bc7d

Browse files
committed
Add support for parsing #[link_ordinal] attribute.
1 parent c57e8eb commit bf4bc7d

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
@@ -2626,6 +2626,11 @@ pub struct CodegenFnAttrs {
26262626
/// probably isn't set when this is set, this is for foreign items while
26272627
/// `#[export_name]` is for Rust-defined functions.
26282628
pub link_name: Option<Symbol>,
2629+
/// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
2630+
/// imported function has in the dynamic library. Note that this must not
2631+
/// be set when `link_name` is set. This is for foreign items with the
2632+
/// "raw-dylib" kind.
2633+
pub link_ordinal: Option<usize>,
26292634
/// The `#[target_feature(enable = "...")]` attribute and the enabled
26302635
/// features (only enabled features are supported right now).
26312636
pub target_features: Vec<Symbol>,
@@ -2685,6 +2690,7 @@ impl CodegenFnAttrs {
26852690
optimize: OptimizeAttr::None,
26862691
export_name: None,
26872692
link_name: None,
2693+
link_ordinal: None,
26882694
target_features: vec![],
26892695
linkage: None,
26902696
link_section: None,

src/librustc_typeck/collect.rs

+38
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,35 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
26032603
}
26042604
} else if attr.check_name(sym::link_name) {
26052605
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+
}
26062635
}
26072636
}
26082637

@@ -2704,6 +2733,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
27042733
codegen_fn_attrs.export_name = Some(name);
27052734
codegen_fn_attrs.link_name = Some(name);
27062735
}
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+
}
27072745

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

0 commit comments

Comments
 (0)