]> git.lizzy.rs Git - rust.git/blob - src/librustc_target/spec/abi.rs
Auto merge of #66256 - CAD97:patch-2, r=RalfJung
[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,
9          Clone, Copy, Debug, 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
67     // Cross-platform ABIs
68     AbiData {abi: Abi::Rust, name: "Rust", generic: true },
69     AbiData {abi: Abi::C, name: "C", generic: true },
70     AbiData {abi: Abi::System, name: "system", generic: true },
71     AbiData {abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
72     AbiData {abi: Abi::RustCall, name: "rust-call", generic: true },
73     AbiData {abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true },
74     AbiData {abi: Abi::Unadjusted, name: "unadjusted", generic: true },
75 ];
76
77 /// Returns the ABI with the given name (if any).
78 pub fn lookup(name: &str) -> Option<Abi> {
79     AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
80 }
81
82 pub fn all_names() -> Vec<&'static str> {
83     AbiDatas.iter().map(|d| d.name).collect()
84 }
85
86 impl Abi {
87     #[inline]
88     pub fn index(self) -> usize {
89         self as usize
90     }
91
92     #[inline]
93     pub fn data(self) -> &'static AbiData {
94         &AbiDatas[self.index()]
95     }
96
97     pub fn name(self) -> &'static str {
98         self.data().name
99     }
100
101     pub fn generic(self) -> bool {
102         self.data().generic
103     }
104 }
105
106 impl fmt::Display for Abi {
107     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108         write!(f, "\"{}\"", self.name())
109     }
110 }