1 use crate::mir
::mono
::Linkage
;
2 use rustc_attr
::{InlineAttr, InstructionSetAttr, OptimizeAttr}
;
3 use rustc_span
::symbol
::Symbol
;
4 use rustc_target
::spec
::SanitizerSet
;
6 #[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)]
7 pub struct CodegenFnAttrs
{
8 pub flags
: CodegenFnAttrFlags
,
9 /// Parsed representation of the `#[inline]` attribute
10 pub inline
: InlineAttr
,
11 /// Parsed representation of the `#[optimize]` attribute
12 pub optimize
: OptimizeAttr
,
13 /// The `#[export_name = "..."]` attribute, indicating a custom symbol a
14 /// function should be exported under
15 pub export_name
: Option
<Symbol
>,
16 /// The `#[link_name = "..."]` attribute, indicating a custom symbol an
17 /// imported function should be imported as. Note that `export_name`
18 /// probably isn't set when this is set, this is for foreign items while
19 /// `#[export_name]` is for Rust-defined functions.
20 pub link_name
: Option
<Symbol
>,
21 /// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
22 /// imported function has in the dynamic library. Note that this must not
23 /// be set when `link_name` is set. This is for foreign items with the
25 pub link_ordinal
: Option
<usize>,
26 /// The `#[target_feature(enable = "...")]` attribute and the enabled
27 /// features (only enabled features are supported right now).
28 pub target_features
: Vec
<Symbol
>,
29 /// The `#[linkage = "..."]` attribute and the value we found.
30 pub linkage
: Option
<Linkage
>,
31 /// The `#[link_section = "..."]` attribute, or what executable section this
32 /// should be placed in.
33 pub link_section
: Option
<Symbol
>,
34 /// The `#[no_sanitize(...)]` attribute. Indicates sanitizers for which
35 /// instrumentation should be disabled inside the annotated function.
36 pub no_sanitize
: SanitizerSet
,
37 /// The `#[instruction_set(set)]` attribute. Indicates if the generated code should
38 /// be generated against a specific instruction set. Only usable on architectures which allow
39 /// switching between multiple instruction sets.
40 pub instruction_set
: Option
<InstructionSetAttr
>,
41 /// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be
43 pub alignment
: Option
<u32>,
47 #[derive(TyEncodable, TyDecodable, HashStable)]
48 pub struct CodegenFnAttrFlags
: u32 {
49 /// `#[cold]`: a hint to LLVM that this function, when called, is never on
52 /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this
53 /// function is never null.
54 const ALLOCATOR
= 1 << 1;
55 /// `#[unwind]`: an indicator that this function may unwind despite what
56 /// its ABI signature may otherwise imply.
57 const UNWIND
= 1 << 2;
58 /// `#[rust_allocator_nounwind]`, an indicator that an imported FFI
59 /// function will never unwind. Probably obsolete by recent changes with
60 /// #[unwind], but hasn't been removed/migrated yet
61 const RUSTC_ALLOCATOR_NOUNWIND
= 1 << 3;
62 /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue
63 /// should be generated.
65 /// `#[no_mangle]`: an indicator that the function's name should be the same
67 const NO_MANGLE
= 1 << 5;
68 /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a
69 /// "weird symbol" for the standard library in that it has slightly
70 /// different linkage, visibility, and reachability rules.
71 const RUSTC_STD_INTERNAL_SYMBOL
= 1 << 6;
72 /// `#[thread_local]`: indicates a static is actually a thread local
74 const THREAD_LOCAL
= 1 << 8;
75 /// `#[used]`: indicates that LLVM can't eliminate this function (but the
78 /// `#[ffi_returns_twice]`, indicates that an extern function can return
80 const FFI_RETURNS_TWICE
= 1 << 10;
81 /// `#[track_caller]`: allow access to the caller location
82 const TRACK_CALLER
= 1 << 11;
83 /// #[ffi_pure]: applies clang's `pure` attribute to a foreign function
85 const FFI_PURE
= 1 << 12;
86 /// #[ffi_const]: applies clang's `const` attribute to a foreign function
88 const FFI_CONST
= 1 << 13;
89 /// #[cmse_nonsecure_entry]: with a TrustZone-M extension, declare a
90 /// function as an entry function from Non-Secure code.
91 const CMSE_NONSECURE_ENTRY
= 1 << 14;
92 /// `#[no_coverage]`: indicates that the function should be ignored by
93 /// the MIR `InstrumentCoverage` pass and not added to the coverage map
95 const NO_COVERAGE
= 1 << 15;
100 pub fn new() -> CodegenFnAttrs
{
102 flags
: CodegenFnAttrFlags
::empty(),
103 inline
: InlineAttr
::None
,
104 optimize
: OptimizeAttr
::None
,
108 target_features
: vec
![],
111 no_sanitize
: SanitizerSet
::empty(),
112 instruction_set
: None
,
117 /// Returns `true` if `#[inline]` or `#[inline(always)]` is present.
118 pub fn requests_inline(&self) -> bool
{
120 InlineAttr
::Hint
| InlineAttr
::Always
=> true,
121 InlineAttr
::None
| InlineAttr
::Never
=> false,
125 /// Returns `true` if it looks like this symbol needs to be exported, for example:
127 /// * `#[no_mangle]` is present
128 /// * `#[export_name(...)]` is present
129 /// * `#[linkage]` is present
130 pub fn contains_extern_indicator(&self) -> bool
{
131 self.flags
.contains(CodegenFnAttrFlags
::NO_MANGLE
)
132 || self.export_name
.is_some()
133 || match self.linkage
{
134 // These are private, so make sure we don't try to consider
136 None
| Some(Linkage
::Internal
| Linkage
::Private
) => false,