]>
Commit | Line | Data |
---|---|---|
dfeec247 | 1 | use crate::mir::mono::Linkage; |
74b04a01 | 2 | use rustc_attr::{InlineAttr, OptimizeAttr}; |
f035d41b | 3 | use rustc_session::config::SanitizerSet; |
dfeec247 | 4 | use rustc_span::symbol::Symbol; |
dfeec247 | 5 | |
3dfed10e | 6 | #[derive(Clone, TyEncodable, TyDecodable, HashStable)] |
dfeec247 XL |
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 | |
24 | /// "raw-dylib" kind. | |
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>, | |
f035d41b XL |
34 | /// The `#[no_sanitize(...)]` attribute. Indicates sanitizers for which |
35 | /// instrumentation should be disabled inside the annotated function. | |
36 | pub no_sanitize: SanitizerSet, | |
dfeec247 XL |
37 | } |
38 | ||
39 | bitflags! { | |
3dfed10e | 40 | #[derive(TyEncodable, TyDecodable, HashStable)] |
dfeec247 XL |
41 | pub struct CodegenFnAttrFlags: u32 { |
42 | /// `#[cold]`: a hint to LLVM that this function, when called, is never on | |
43 | /// the hot path. | |
44 | const COLD = 1 << 0; | |
45 | /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this | |
46 | /// function is never null. | |
47 | const ALLOCATOR = 1 << 1; | |
48 | /// `#[unwind]`: an indicator that this function may unwind despite what | |
49 | /// its ABI signature may otherwise imply. | |
50 | const UNWIND = 1 << 2; | |
51 | /// `#[rust_allocator_nounwind]`, an indicator that an imported FFI | |
52 | /// function will never unwind. Probably obsolete by recent changes with | |
53 | /// #[unwind], but hasn't been removed/migrated yet | |
54 | const RUSTC_ALLOCATOR_NOUNWIND = 1 << 3; | |
55 | /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue | |
56 | /// should be generated. | |
57 | const NAKED = 1 << 4; | |
58 | /// `#[no_mangle]`: an indicator that the function's name should be the same | |
59 | /// as its symbol. | |
60 | const NO_MANGLE = 1 << 5; | |
61 | /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a | |
62 | /// "weird symbol" for the standard library in that it has slightly | |
63 | /// different linkage, visibility, and reachability rules. | |
64 | const RUSTC_STD_INTERNAL_SYMBOL = 1 << 6; | |
dfeec247 XL |
65 | /// `#[thread_local]`: indicates a static is actually a thread local |
66 | /// piece of memory | |
67 | const THREAD_LOCAL = 1 << 8; | |
68 | /// `#[used]`: indicates that LLVM can't eliminate this function (but the | |
69 | /// linker can!). | |
70 | const USED = 1 << 9; | |
71 | /// `#[ffi_returns_twice]`, indicates that an extern function can return | |
72 | /// multiple times | |
73 | const FFI_RETURNS_TWICE = 1 << 10; | |
74 | /// `#[track_caller]`: allow access to the caller location | |
75 | const TRACK_CALLER = 1 << 11; | |
f9f354fc XL |
76 | /// #[ffi_pure]: applies clang's `pure` attribute to a foreign function |
77 | /// declaration. | |
f035d41b | 78 | const FFI_PURE = 1 << 12; |
f9f354fc XL |
79 | /// #[ffi_const]: applies clang's `const` attribute to a foreign function |
80 | /// declaration. | |
f035d41b | 81 | const FFI_CONST = 1 << 13; |
dfeec247 XL |
82 | } |
83 | } | |
84 | ||
85 | impl CodegenFnAttrs { | |
86 | pub fn new() -> CodegenFnAttrs { | |
87 | CodegenFnAttrs { | |
88 | flags: CodegenFnAttrFlags::empty(), | |
89 | inline: InlineAttr::None, | |
90 | optimize: OptimizeAttr::None, | |
91 | export_name: None, | |
92 | link_name: None, | |
93 | link_ordinal: None, | |
94 | target_features: vec![], | |
95 | linkage: None, | |
96 | link_section: None, | |
f035d41b | 97 | no_sanitize: SanitizerSet::empty(), |
dfeec247 XL |
98 | } |
99 | } | |
100 | ||
101 | /// Returns `true` if `#[inline]` or `#[inline(always)]` is present. | |
102 | pub fn requests_inline(&self) -> bool { | |
103 | match self.inline { | |
104 | InlineAttr::Hint | InlineAttr::Always => true, | |
105 | InlineAttr::None | InlineAttr::Never => false, | |
106 | } | |
107 | } | |
108 | ||
109 | /// Returns `true` if it looks like this symbol needs to be exported, for example: | |
110 | /// | |
111 | /// * `#[no_mangle]` is present | |
112 | /// * `#[export_name(...)]` is present | |
113 | /// * `#[linkage]` is present | |
114 | pub fn contains_extern_indicator(&self) -> bool { | |
115 | self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) | |
116 | || self.export_name.is_some() | |
117 | || match self.linkage { | |
118 | // These are private, so make sure we don't try to consider | |
119 | // them external. | |
ba9703b0 | 120 | None | Some(Linkage::Internal | Linkage::Private) => false, |
dfeec247 XL |
121 | Some(_) => true, |
122 | } | |
123 | } | |
124 | } |