]> git.lizzy.rs Git - rust.git/blob - src/librustc_middle/middle/codegen_fn_attrs.rs
pin docs: add some forward references
[rust.git] / src / librustc_middle / middle / codegen_fn_attrs.rs
1 use crate::mir::mono::Linkage;
2 use rustc_attr::{InlineAttr, OptimizeAttr};
3 use rustc_session::config::SanitizerSet;
4 use rustc_span::symbol::Symbol;
5
6 #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
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>,
34     /// The `#[no_sanitize(...)]` attribute. Indicates sanitizers for which
35     /// instrumentation should be disabled inside the annotated function.
36     pub no_sanitize: SanitizerSet,
37 }
38
39 bitflags! {
40     #[derive(RustcEncodable, RustcDecodable, HashStable)]
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;
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;
76         /// #[ffi_pure]: applies clang's `pure` attribute to a foreign function
77         /// declaration.
78         const FFI_PURE                  = 1 << 12;
79         /// #[ffi_const]: applies clang's `const` attribute to a foreign function
80         /// declaration.
81         const FFI_CONST                 = 1 << 13;
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,
97             no_sanitize: SanitizerSet::empty(),
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.
120                 None | Some(Linkage::Internal | Linkage::Private) => false,
121                 Some(_) => true,
122             }
123     }
124 }