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