Merge link_name and export_name

This commit is contained in:
bjorn3 2025-08-15 09:37:24 +00:00
parent f3ef465ffb
commit 460519a7f5
8 changed files with 33 additions and 44 deletions

View file

@ -513,7 +513,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-module", module));
let name =
codegen_fn_attrs.link_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id()));
codegen_fn_attrs.symbol_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id()));
let name = name.as_str();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-name", name));
}

View file

@ -857,7 +857,7 @@ pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>(
instance: Instance<'tcx>,
) -> bool {
fn is_llvm_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
if let Some(name) = tcx.codegen_fn_attrs(def_id).link_name {
if let Some(name) = tcx.codegen_fn_attrs(def_id).symbol_name {
name.as_str().starts_with("llvm.")
} else {
false

View file

@ -189,7 +189,7 @@ fn process_builtin_attrs(
match p {
AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
AttributeKind::ExportName { name, .. } => {
codegen_fn_attrs.export_name = Some(*name)
codegen_fn_attrs.symbol_name = Some(*name)
}
AttributeKind::Inline(inline, span) => {
codegen_fn_attrs.inline = *inline;
@ -197,7 +197,13 @@ fn process_builtin_attrs(
}
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
AttributeKind::LinkName { name, .. } => {
// FIXME Remove check for foreign functions once #[link_name] on non-foreign
// functions is a hard error
if tcx.is_foreign_item(did) {
codegen_fn_attrs.symbol_name = Some(*name);
}
}
AttributeKind::LinkOrdinal { ordinal, span } => {
codegen_fn_attrs.link_ordinal = Some(*ordinal);
interesting_spans.link_ordinal = Some(*span);
@ -417,7 +423,7 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
// * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
// both for exports and imports through foreign items. This is handled further,
// during symbol mangling logic.
} else if codegen_fn_attrs.link_name.is_some() {
} else if codegen_fn_attrs.symbol_name.is_some() {
// * This can be overridden with the `#[link_name]` attribute
} else {
// NOTE: there's one more exception that we cannot apply here. On wasm,
@ -472,7 +478,7 @@ fn check_result(
}
// error when specifying link_name together with link_ordinal
if let Some(_) = codegen_fn_attrs.link_name
if let Some(_) = codegen_fn_attrs.symbol_name
&& let Some(_) = codegen_fn_attrs.link_ordinal
{
let msg = "cannot use `#[link_name]` with `#[link_ordinal]`";
@ -523,8 +529,7 @@ fn handle_lang_items(
&& let Some(link_name) = lang_item.link_name()
{
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
codegen_fn_attrs.export_name = Some(link_name);
codegen_fn_attrs.link_name = Some(link_name);
codegen_fn_attrs.symbol_name = Some(link_name);
}
// error when using no_mangle on a lang item item

View file

@ -179,7 +179,7 @@ impl ClashingExternDeclarations {
/// symbol's name.
fn name_of_extern_decl(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> SymbolName {
if let Some((overridden_link_name, overridden_link_name_span)) =
tcx.codegen_fn_attrs(fi).link_name.map(|overridden_link_name| {
tcx.codegen_fn_attrs(fi).symbol_name.map(|overridden_link_name| {
// FIXME: Instead of searching through the attributes again to get span
// information, we could have codegen_fn_attrs also give span information back for
// where the attribute was defined. However, until this is found to be a

View file

@ -701,7 +701,7 @@ impl<'tcx> Collector<'tcx> {
.link_ordinal
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
let name = codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item));
let name = codegen_fn_attrs.symbol_name.unwrap_or_else(|| self.tcx.item_name(item));
if self.tcx.sess.target.binary_format == BinaryFormat::Elf {
let name = name.as_str();

View file

@ -36,14 +36,10 @@ pub struct CodegenFnAttrs {
pub inline: InlineAttr,
/// Parsed representation of the `#[optimize]` attribute
pub optimize: OptimizeAttr,
/// The `#[export_name = "..."]` attribute, indicating a custom symbol a
/// function should be exported under
pub export_name: Option<Symbol>,
/// The `#[link_name = "..."]` attribute, indicating a custom symbol an
/// imported function should be imported as. Note that `export_name`
/// probably isn't set when this is set, this is for foreign items while
/// `#[export_name]` is for Rust-defined functions.
pub link_name: Option<Symbol>,
/// The name this function will be imported/exported under. This can be set
/// using the `#[export_name = "..."]` or `#[link_name = "..."]` attribute
/// depending on if this is a function definition or foreign function.
pub symbol_name: Option<Symbol>,
/// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
/// imported function has in the dynamic library. Note that this must not
/// be set when `link_name` is set. This is for foreign items with the
@ -170,8 +166,7 @@ impl CodegenFnAttrs {
flags: CodegenFnAttrFlags::empty(),
inline: InlineAttr::None,
optimize: OptimizeAttr::Default,
export_name: None,
link_name: None,
symbol_name: None,
link_ordinal: None,
target_features: vec![],
safe_target_features: false,
@ -200,7 +195,7 @@ impl CodegenFnAttrs {
self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
|| self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|| self.export_name.is_some()
|| self.symbol_name.is_some()
|| match self.linkage {
// These are private, so make sure we don't try to consider
// them external.

View file

@ -204,13 +204,9 @@ fn compute_symbol_name<'tcx>(
// mangling scheme can't be used. For example both the GCC backend and
// Rust-for-Linux don't support some of the characters used by the
// legacy symbol mangling scheme.
let name = if tcx.is_foreign_item(def_id) {
if let Some(name) = attrs.link_name { name } else { tcx.item_name(def_id) }
} else {
if let Some(name) = attrs.export_name { name } else { tcx.item_name(def_id) }
};
let name = if let Some(name) = attrs.symbol_name { name } else { tcx.item_name(def_id) };
return v0::mangle_internal_symbol(tcx, name.as_str());
return v0::mangle_internal_symbol(tcx, name.as_str());
}
let wasm_import_module_exception_force_mangling = {
@ -235,23 +231,16 @@ fn compute_symbol_name<'tcx>(
&& tcx.wasm_import_module_map(LOCAL_CRATE).contains_key(&def_id.into())
};
if let Some(name) = attrs.link_name
&& !wasm_import_module_exception_force_mangling
{
// Use provided name
return name.to_string();
}
if !wasm_import_module_exception_force_mangling {
if let Some(name) = attrs.symbol_name {
// Use provided name
return name.to_string();
}
if let Some(name) = attrs.export_name {
// Use provided name
return name.to_string();
}
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
&& !wasm_import_module_exception_force_mangling
{
// Don't mangle
return tcx.item_name(def_id).to_string();
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
// Don't mangle
return tcx.item_name(def_id).to_string();
}
}
// If we're dealing with an instance of a function that's inlined from

View file

@ -146,7 +146,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
return interp_ok(());
}
// Skip over items without an explicitly defined symbol name.
if !(attrs.export_name.is_some()
if !(attrs.symbol_name.is_some()
|| attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
|| attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL))
{