diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /compiler/rustc_middle/src/middle/codegen_fn_attrs.rs | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_middle/src/middle/codegen_fn_attrs.rs')
-rw-r--r-- | compiler/rustc_middle/src/middle/codegen_fn_attrs.rs | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs new file mode 100644 index 000000000..45d33a165 --- /dev/null +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -0,0 +1,146 @@ +use crate::mir::mono::Linkage; +use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_span::symbol::Symbol; +use rustc_target::spec::SanitizerSet; + +#[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)] +pub struct CodegenFnAttrs { + pub flags: CodegenFnAttrFlags, + /// Parsed representation of the `#[inline]` attribute + 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 `#[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 + /// "raw-dylib" kind. + pub link_ordinal: Option<u16>, + /// The `#[target_feature(enable = "...")]` attribute and the enabled + /// features (only enabled features are supported right now). + pub target_features: Vec<Symbol>, + /// The `#[linkage = "..."]` attribute and the value we found. + pub linkage: Option<Linkage>, + /// The `#[link_section = "..."]` attribute, or what executable section this + /// should be placed in. + pub link_section: Option<Symbol>, + /// The `#[no_sanitize(...)]` attribute. Indicates sanitizers for which + /// instrumentation should be disabled inside the annotated function. + pub no_sanitize: SanitizerSet, + /// The `#[instruction_set(set)]` attribute. Indicates if the generated code should + /// be generated against a specific instruction set. Only usable on architectures which allow + /// switching between multiple instruction sets. + pub instruction_set: Option<InstructionSetAttr>, + /// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be + /// aligned to. + pub alignment: Option<u32>, +} + +bitflags! { + #[derive(TyEncodable, TyDecodable, HashStable)] + pub struct CodegenFnAttrFlags: u32 { + /// `#[cold]`: a hint to LLVM that this function, when called, is never on + /// the hot path. + const COLD = 1 << 0; + /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this + /// function is never null and the function has no side effects other than allocating. + const ALLOCATOR = 1 << 1; + /// An indicator that function will never unwind. Will become obsolete + /// once C-unwind is fully stabilized. + const NEVER_UNWIND = 1 << 3; + /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue + /// should be generated. + const NAKED = 1 << 4; + /// `#[no_mangle]`: an indicator that the function's name should be the same + /// as its symbol. + const NO_MANGLE = 1 << 5; + /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a + /// "weird symbol" for the standard library in that it has slightly + /// different linkage, visibility, and reachability rules. + const RUSTC_STD_INTERNAL_SYMBOL = 1 << 6; + /// `#[thread_local]`: indicates a static is actually a thread local + /// piece of memory + const THREAD_LOCAL = 1 << 8; + /// `#[used]`: indicates that LLVM can't eliminate this function (but the + /// linker can!). + const USED = 1 << 9; + /// `#[ffi_returns_twice]`, indicates that an extern function can return + /// multiple times + const FFI_RETURNS_TWICE = 1 << 10; + /// `#[track_caller]`: allow access to the caller location + const TRACK_CALLER = 1 << 11; + /// #[ffi_pure]: applies clang's `pure` attribute to a foreign function + /// declaration. + const FFI_PURE = 1 << 12; + /// #[ffi_const]: applies clang's `const` attribute to a foreign function + /// declaration. + const FFI_CONST = 1 << 13; + /// #[cmse_nonsecure_entry]: with a TrustZone-M extension, declare a + /// function as an entry function from Non-Secure code. + const CMSE_NONSECURE_ENTRY = 1 << 14; + /// `#[no_coverage]`: indicates that the function should be ignored by + /// the MIR `InstrumentCoverage` pass and not added to the coverage map + /// during codegen. + const NO_COVERAGE = 1 << 15; + /// `#[used(linker)]`: indicates that LLVM nor the linker can eliminate this function. + const USED_LINKER = 1 << 16; + /// `#[rustc_deallocator]`: a hint to LLVM that the function only deallocates memory. + const DEALLOCATOR = 1 << 17; + /// `#[rustc_reallocator]`: a hint to LLVM that the function only reallocates memory. + const REALLOCATOR = 1 << 18; + /// `#[rustc_allocator_zeroed]`: a hint to LLVM that the function only allocates zeroed memory. + const ALLOCATOR_ZEROED = 1 << 19; + } +} + +impl CodegenFnAttrs { + pub const EMPTY: &'static Self = &Self::new(); + + pub const fn new() -> CodegenFnAttrs { + CodegenFnAttrs { + flags: CodegenFnAttrFlags::empty(), + inline: InlineAttr::None, + optimize: OptimizeAttr::None, + export_name: None, + link_name: None, + link_ordinal: None, + target_features: vec![], + linkage: None, + link_section: None, + no_sanitize: SanitizerSet::empty(), + instruction_set: None, + alignment: None, + } + } + + /// Returns `true` if `#[inline]` or `#[inline(always)]` is present. + pub fn requests_inline(&self) -> bool { + match self.inline { + InlineAttr::Hint | InlineAttr::Always => true, + InlineAttr::None | InlineAttr::Never => false, + } + } + + /// Returns `true` if it looks like this symbol needs to be exported, for example: + /// + /// * `#[no_mangle]` is present + /// * `#[export_name(...)]` is present + /// * `#[linkage]` is present + pub fn contains_extern_indicator(&self) -> bool { + self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) + || self.export_name.is_some() + || match self.linkage { + // These are private, so make sure we don't try to consider + // them external. + None | Some(Linkage::Internal | Linkage::Private) => false, + Some(_) => true, + } + } +} |