]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/codegen_fn_attrs.rs
Rollup merge of #70038 - DutchGhost:const-forget-tests, r=RalfJung
[rust.git] / src / librustc / middle / codegen_fn_attrs.rs
1 use crate::mir::mono::Linkage;
2 use rustc_attr::{InlineAttr, OptimizeAttr};
3 use rustc_span::symbol::Symbol;
4
5 #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
6 pub struct CodegenFnAttrs {
7     pub flags: CodegenFnAttrFlags,
8     /// Parsed representation of the `#[inline]` attribute
9     pub inline: InlineAttr,
10     /// Parsed representation of the `#[optimize]` attribute
11     pub optimize: OptimizeAttr,
12     /// The `#[export_name = "..."]` attribute, indicating a custom symbol a
13     /// function should be exported under
14     pub export_name: Option<Symbol>,
15     /// The `#[link_name = "..."]` attribute, indicating a custom symbol an
16     /// imported function should be imported as. Note that `export_name`
17     /// probably isn't set when this is set, this is for foreign items while
18     /// `#[export_name]` is for Rust-defined functions.
19     pub link_name: Option<Symbol>,
20     /// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
21     /// imported function has in the dynamic library. Note that this must not
22     /// be set when `link_name` is set. This is for foreign items with the
23     /// "raw-dylib" kind.
24     pub link_ordinal: Option<usize>,
25     /// The `#[target_feature(enable = "...")]` attribute and the enabled
26     /// features (only enabled features are supported right now).
27     pub target_features: Vec<Symbol>,
28     /// The `#[linkage = "..."]` attribute and the value we found.
29     pub linkage: Option<Linkage>,
30     /// The `#[link_section = "..."]` attribute, or what executable section this
31     /// should be placed in.
32     pub link_section: Option<Symbol>,
33 }
34
35 bitflags! {
36     #[derive(RustcEncodable, RustcDecodable, HashStable)]
37     pub struct CodegenFnAttrFlags: u32 {
38         /// `#[cold]`: a hint to LLVM that this function, when called, is never on
39         /// the hot path.
40         const COLD                      = 1 << 0;
41         /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this
42         /// function is never null.
43         const ALLOCATOR                 = 1 << 1;
44         /// `#[unwind]`: an indicator that this function may unwind despite what
45         /// its ABI signature may otherwise imply.
46         const UNWIND                    = 1 << 2;
47         /// `#[rust_allocator_nounwind]`, an indicator that an imported FFI
48         /// function will never unwind. Probably obsolete by recent changes with
49         /// #[unwind], but hasn't been removed/migrated yet
50         const RUSTC_ALLOCATOR_NOUNWIND  = 1 << 3;
51         /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue
52         /// should be generated.
53         const NAKED                     = 1 << 4;
54         /// `#[no_mangle]`: an indicator that the function's name should be the same
55         /// as its symbol.
56         const NO_MANGLE                 = 1 << 5;
57         /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a
58         /// "weird symbol" for the standard library in that it has slightly
59         /// different linkage, visibility, and reachability rules.
60         const RUSTC_STD_INTERNAL_SYMBOL = 1 << 6;
61         /// `#[thread_local]`: indicates a static is actually a thread local
62         /// piece of memory
63         const THREAD_LOCAL              = 1 << 8;
64         /// `#[used]`: indicates that LLVM can't eliminate this function (but the
65         /// linker can!).
66         const USED                      = 1 << 9;
67         /// `#[ffi_returns_twice]`, indicates that an extern function can return
68         /// multiple times
69         const FFI_RETURNS_TWICE         = 1 << 10;
70         /// `#[track_caller]`: allow access to the caller location
71         const TRACK_CALLER              = 1 << 11;
72         /// `#[no_sanitize(address)]`: disables address sanitizer instrumentation
73         const NO_SANITIZE_ADDRESS = 1 << 12;
74         /// `#[no_sanitize(memory)]`: disables memory sanitizer instrumentation
75         const NO_SANITIZE_MEMORY  = 1 << 13;
76         /// `#[no_sanitize(thread)]`: disables thread sanitizer instrumentation
77         const NO_SANITIZE_THREAD  = 1 << 14;
78         /// All `#[no_sanitize(...)]` attributes.
79         const NO_SANITIZE_ANY = Self::NO_SANITIZE_ADDRESS.bits | Self::NO_SANITIZE_MEMORY.bits | Self::NO_SANITIZE_THREAD.bits;
80     }
81 }
82
83 impl CodegenFnAttrs {
84     pub fn new() -> CodegenFnAttrs {
85         CodegenFnAttrs {
86             flags: CodegenFnAttrFlags::empty(),
87             inline: InlineAttr::None,
88             optimize: OptimizeAttr::None,
89             export_name: None,
90             link_name: None,
91             link_ordinal: None,
92             target_features: vec![],
93             linkage: None,
94             link_section: None,
95         }
96     }
97
98     /// Returns `true` if `#[inline]` or `#[inline(always)]` is present.
99     pub fn requests_inline(&self) -> bool {
100         match self.inline {
101             InlineAttr::Hint | InlineAttr::Always => true,
102             InlineAttr::None | InlineAttr::Never => false,
103         }
104     }
105
106     /// Returns `true` if it looks like this symbol needs to be exported, for example:
107     ///
108     /// * `#[no_mangle]` is present
109     /// * `#[export_name(...)]` is present
110     /// * `#[linkage]` is present
111     pub fn contains_extern_indicator(&self) -> bool {
112         self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
113             || self.export_name.is_some()
114             || match self.linkage {
115                 // These are private, so make sure we don't try to consider
116                 // them external.
117                 None | Some(Linkage::Internal) | Some(Linkage::Private) => false,
118                 Some(_) => true,
119             }
120     }
121 }