]> git.proxmox.com Git - rustc.git/blame - src/librustc_middle/middle/codegen_fn_attrs.rs
New upstream version 1.47.0~beta.2+dfsg1
[rustc.git] / src / librustc_middle / middle / codegen_fn_attrs.rs
CommitLineData
dfeec247 1use crate::mir::mono::Linkage;
74b04a01 2use rustc_attr::{InlineAttr, OptimizeAttr};
f035d41b 3use rustc_session::config::SanitizerSet;
dfeec247 4use rustc_span::symbol::Symbol;
dfeec247 5
3dfed10e 6#[derive(Clone, TyEncodable, TyDecodable, HashStable)]
dfeec247
XL
7pub 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
39bitflags! {
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
85impl 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}