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