]> git.lizzy.rs Git - rust.git/blob - src/librustc_target/spec/abi.rs
pin docs: add some forward references
[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     // Multiplatform / generic ABIs
15     //
16     // These ABIs come first because every time we add a new ABI, we
17     // have to re-bless all the hashing tests. These are used in many
18     // places, so giving them stable values reduces test churn. The
19     // specific values are meaningless.
20     Rust = 0,
21     C = 1,
22
23     // Single platform ABIs
24     Cdecl,
25     Stdcall,
26     Fastcall,
27     Vectorcall,
28     Thiscall,
29     Aapcs,
30     Win64,
31     SysV64,
32     PtxKernel,
33     Msp430Interrupt,
34     X86Interrupt,
35     AmdGpuKernel,
36     EfiApi,
37     AvrInterrupt,
38     AvrNonBlockingInterrupt,
39
40     // Multiplatform / generic ABIs
41     System,
42     RustIntrinsic,
43     RustCall,
44     PlatformIntrinsic,
45     Unadjusted,
46 }
47
48 #[derive(Copy, Clone)]
49 pub struct AbiData {
50     abi: Abi,
51
52     /// Name of this ABI as we like it called.
53     name: &'static str,
54
55     /// A generic ABI is supported on all platforms.
56     generic: bool,
57 }
58
59 #[allow(non_upper_case_globals)]
60 const AbiDatas: &[AbiData] = &[
61     // Cross-platform ABIs
62     AbiData { abi: Abi::Rust, name: "Rust", generic: true },
63     AbiData { abi: Abi::C, name: "C", generic: true },
64     // Platform-specific ABIs
65     AbiData { abi: Abi::Cdecl, name: "cdecl", generic: false },
66     AbiData { abi: Abi::Stdcall, name: "stdcall", generic: false },
67     AbiData { abi: Abi::Fastcall, name: "fastcall", generic: false },
68     AbiData { abi: Abi::Vectorcall, name: "vectorcall", generic: false },
69     AbiData { abi: Abi::Thiscall, name: "thiscall", generic: false },
70     AbiData { abi: Abi::Aapcs, name: "aapcs", generic: false },
71     AbiData { abi: Abi::Win64, name: "win64", generic: false },
72     AbiData { abi: Abi::SysV64, name: "sysv64", generic: false },
73     AbiData { abi: Abi::PtxKernel, name: "ptx-kernel", generic: false },
74     AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false },
75     AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false },
76     AbiData { abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false },
77     AbiData { abi: Abi::EfiApi, name: "efiapi", generic: false },
78     AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false },
79     AbiData {
80         abi: Abi::AvrNonBlockingInterrupt,
81         name: "avr-non-blocking-interrupt",
82         generic: false,
83     },
84     // Cross-platform ABIs
85     AbiData { abi: Abi::System, name: "system", generic: true },
86     AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
87     AbiData { abi: Abi::RustCall, name: "rust-call", generic: true },
88     AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true },
89     AbiData { abi: Abi::Unadjusted, name: "unadjusted", generic: true },
90 ];
91
92 /// Returns the ABI with the given name (if any).
93 pub fn lookup(name: &str) -> Option<Abi> {
94     AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
95 }
96
97 pub fn all_names() -> Vec<&'static str> {
98     AbiDatas.iter().map(|d| d.name).collect()
99 }
100
101 impl Abi {
102     #[inline]
103     pub fn index(self) -> usize {
104         self as usize
105     }
106
107     #[inline]
108     pub fn data(self) -> &'static AbiData {
109         &AbiDatas[self.index()]
110     }
111
112     pub fn name(self) -> &'static str {
113         self.data().name
114     }
115
116     pub fn generic(self) -> bool {
117         self.data().generic
118     }
119 }
120
121 impl fmt::Display for Abi {
122     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123         write!(f, "\"{}\"", self.name())
124     }
125 }