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