]> git.lizzy.rs Git - rust.git/blob - src/librustc_target/spec/abi.rs
Auto merge of #63871 - BatmanAoD:FloatFnMustUse, r=withoutboats
[rust.git] / src / librustc_target / spec / abi.rs
1 use std::fmt;
2
3 #[cfg(test)]
4 mod tests;
5
6 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
7 pub enum Abi {
8     // N.B., this ordering MUST match the AbiDatas array below.
9     // (This is ensured by the test indices_are_correct().)
10
11     // Single platform ABIs
12     Cdecl,
13     Stdcall,
14     Fastcall,
15     Vectorcall,
16     Thiscall,
17     Aapcs,
18     Win64,
19     SysV64,
20     PtxKernel,
21     Msp430Interrupt,
22     X86Interrupt,
23     AmdGpuKernel,
24     EfiApi,
25
26     // Multiplatform / generic ABIs
27     Rust,
28     C,
29     System,
30     RustIntrinsic,
31     RustCall,
32     PlatformIntrinsic,
33     Unadjusted
34 }
35
36 #[derive(Copy, Clone)]
37 pub struct AbiData {
38     abi: Abi,
39
40     /// Name of this ABI as we like it called.
41     name: &'static str,
42
43     /// A generic ABI is supported on all platforms.
44     generic: bool,
45 }
46
47 #[allow(non_upper_case_globals)]
48 const AbiDatas: &[AbiData] = &[
49     // Platform-specific ABIs
50     AbiData {abi: Abi::Cdecl, name: "cdecl", generic: false },
51     AbiData {abi: Abi::Stdcall, name: "stdcall", generic: false },
52     AbiData {abi: Abi::Fastcall, name: "fastcall", generic: false },
53     AbiData {abi: Abi::Vectorcall, name: "vectorcall", generic: false},
54     AbiData {abi: Abi::Thiscall, name: "thiscall", generic: false},
55     AbiData {abi: Abi::Aapcs, name: "aapcs", generic: false },
56     AbiData {abi: Abi::Win64, name: "win64", generic: false },
57     AbiData {abi: Abi::SysV64, name: "sysv64", generic: false },
58     AbiData {abi: Abi::PtxKernel, name: "ptx-kernel", generic: false },
59     AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false },
60     AbiData {abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false },
61     AbiData {abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false },
62     AbiData {abi: Abi::EfiApi, name: "efiapi", generic: false },
63
64     // Cross-platform ABIs
65     AbiData {abi: Abi::Rust, name: "Rust", generic: true },
66     AbiData {abi: Abi::C, name: "C", generic: true },
67     AbiData {abi: Abi::System, name: "system", generic: true },
68     AbiData {abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
69     AbiData {abi: Abi::RustCall, name: "rust-call", generic: true },
70     AbiData {abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true },
71     AbiData {abi: Abi::Unadjusted, name: "unadjusted", generic: true },
72 ];
73
74 /// Returns the ABI with the given name (if any).
75 pub fn lookup(name: &str) -> Option<Abi> {
76     AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
77 }
78
79 pub fn all_names() -> Vec<&'static str> {
80     AbiDatas.iter().map(|d| d.name).collect()
81 }
82
83 impl Abi {
84     #[inline]
85     pub fn index(self) -> usize {
86         self as usize
87     }
88
89     #[inline]
90     pub fn data(self) -> &'static AbiData {
91         &AbiDatas[self.index()]
92     }
93
94     pub fn name(self) -> &'static str {
95         self.data().name
96     }
97
98     pub fn generic(self) -> bool {
99         self.data().generic
100     }
101 }
102
103 impl fmt::Display for Abi {
104     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105         write!(f, "\"{}\"", self.name())
106     }
107 }