Skip to content

Port #[link] to the new attribute parsing infrastructure #143193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3323,6 +3323,7 @@ dependencies = [
"rustc_macros",
"rustc_session",
"rustc_span",
"rustc_target",
"thin-vec",
]

Expand Down Expand Up @@ -3880,6 +3881,7 @@ dependencies = [
"rustc_ast_lowering",
"rustc_ast_passes",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_borrowck",
"rustc_builtin_macros",
Expand Down Expand Up @@ -4431,6 +4433,7 @@ dependencies = [
"rand 0.9.1",
"rustc_abi",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
Expand Down
117 changes: 117 additions & 0 deletions compiler/rustc_attr_data_structures/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,120 @@ pub enum CfgEntry {
Version(Option<RustcVersion>, Span),
}

/// Different ways that the PE Format can decorate a symbol name.
/// From <https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-name-type>
#[derive(
Copy,
Clone,
Debug,
Encodable,
Decodable,
HashStable_Generic,
PartialEq,
Eq,
PrintAttribute
)]
pub enum PeImportNameType {
/// IMPORT_ORDINAL
/// Uses the ordinal (i.e., a number) rather than the name.
Ordinal(u16),
/// Same as IMPORT_NAME
/// Name is decorated with all prefixes and suffixes.
Decorated,
/// Same as IMPORT_NAME_NOPREFIX
/// Prefix (e.g., the leading `_` or `@`) is skipped, but suffix is kept.
NoPrefix,
/// Same as IMPORT_NAME_UNDECORATE
/// Prefix (e.g., the leading `_` or `@`) and suffix (the first `@` and all
/// trailing characters) are skipped.
Undecorated,
}

#[derive(
Copy,
Clone,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Encodable,
Decodable,
PrintAttribute
)]
#[derive(HashStable_Generic)]
pub enum NativeLibKind {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type was moved here because it is needed for the link attribute and the original location caused a dependency cycle

/// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC)
Static {
/// Whether to bundle objects from static library into produced rlib
bundle: Option<bool>,
/// Whether to link static library without throwing any object files away
whole_archive: Option<bool>,
},
/// Dynamic library (e.g. `libfoo.so` on Linux)
/// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC).
Dylib {
/// Whether the dynamic library will be linked only if it satisfies some undefined symbols
as_needed: Option<bool>,
},
/// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library.
/// On Linux, it refers to a generated shared library stub.
RawDylib,
/// A macOS-specific kind of dynamic libraries.
Framework {
/// Whether the framework will be linked only if it satisfies some undefined symbols
as_needed: Option<bool>,
},
/// Argument which is passed to linker, relative order with libraries and other arguments
/// is preserved
LinkArg,

/// Module imported from WebAssembly
WasmImportModule,

/// The library kind wasn't specified, `Dylib` is currently used as a default.
Unspecified,
}

impl NativeLibKind {
pub fn has_modifiers(&self) -> bool {
match self {
NativeLibKind::Static { bundle, whole_archive } => {
bundle.is_some() || whole_archive.is_some()
}
NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => {
as_needed.is_some()
}
NativeLibKind::RawDylib
| NativeLibKind::Unspecified
| NativeLibKind::LinkArg
| NativeLibKind::WasmImportModule => false,
}
}

pub fn is_statically_included(&self) -> bool {
matches!(self, NativeLibKind::Static { .. })
}

pub fn is_dllimport(&self) -> bool {
matches!(
self,
NativeLibKind::Dylib { .. } | NativeLibKind::RawDylib | NativeLibKind::Unspecified
)
}
}

#[derive(Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
pub struct LinkEntry {
pub span: Span,
pub kind: NativeLibKind,
pub name: Symbol,
pub cfg: Option<CfgEntry>,
pub verbatim: Option<bool>,
pub import_name_type: Option<(PeImportNameType, Span)>,
}

/// Represents parsed *built-in* inert attributes.
///
/// ## Overview
Expand Down Expand Up @@ -319,6 +433,9 @@ pub enum AttributeKind {
/// Represents `#[inline]` and `#[rustc_force_inline]`.
Inline(InlineAttr, Span),

/// Represents `#[link]`.
Link(ThinVec<LinkEntry>, Span),

/// Represents `#[link_name]`.
LinkName { name: Symbol, span: Span },

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl AttributeKind {
Fundamental { .. } => Yes,
Ignore { .. } => No,
Inline(..) => No,
Link(..) => No,
LinkName { .. } => Yes,
LinkOrdinal { .. } => No,
LinkSection { .. } => No,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ rustc_lexer = { path = "../rustc_lexer" }
rustc_macros = { path = "../rustc_macros" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
thin-vec = "0.2.12"
# tidy-alphabetical-end
53 changes: 53 additions & 0 deletions compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,56 @@ attr_parsing_unused_multiple =

-attr_parsing_previously_accepted =
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!


attr_parsing_as_needed_compatibility =
linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds

attr_parsing_bundle_needs_static =
linking modifier `bundle` is only compatible with `static` linking kind

attr_parsing_empty_link_name =
link name must not be empty
.label = empty link name

attr_parsing_import_name_type_raw =
import name type can only be used with link kind `raw-dylib`

attr_parsing_import_name_type_x86 =
import name type is only supported on x86

attr_parsing_incompatible_wasm_link =
`wasm_import_module` is incompatible with other arguments in `#[link]` attributes

attr_parsing_invalid_link_modifier =
invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed

attr_parsing_link_arg_unstable =
link kind `link-arg` is unstable

attr_parsing_link_cfg_unstable =
link cfg is unstable

attr_parsing_link_framework_apple =
link kind `framework` is only supported on Apple targets

attr_parsing_link_requires_name =
`#[link]` attribute requires a `name = "string"` argument
.label = missing `name` argument

attr_parsing_multiple_modifiers =
multiple `{$modifier}` modifiers in a single `modifiers` argument

attr_parsing_multiple_renamings =
multiple renamings were specified for library `{$lib_name}`
attr_parsing_raw_dylib_no_nul =
link name must not contain NUL characters if link kind is `raw-dylib`

attr_parsing_raw_dylib_elf_unstable =
link kind `raw-dylib` is unstable on ELF platforms

attr_parsing_raw_dylib_only_windows =
link kind `raw-dylib` is only supported on Windows targets

attr_parsing_whole_archive_needs_static =
linking modifier `whole-archive` is only compatible with `static` linking kind
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn parse_cfg_attr<'c, S: Stage>(
parse_cfg_entry(cx, single)
}

fn parse_cfg_entry<S: Stage>(
pub(crate) fn parse_cfg_entry<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
item: &MetaItemOrLitParser<'_>,
) -> Option<CfgEntry> {
Expand Down
Loading
Loading