]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/abi.rs
Add support for the Haiku operating system on x86 and x86_64 machines
[rust.git] / src / libsyntax / abi.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::fmt;
12
13 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
14 #[allow(non_camel_case_types)]
15 pub enum Os {
16     Windows,
17     Macos,
18     Linux,
19     Android,
20     Freebsd,
21     iOS,
22     Dragonfly,
23     Bitrig,
24     Netbsd,
25     Openbsd,
26     NaCl,
27     Haiku,
28     Solaris,
29 }
30
31 #[derive(PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
32 pub enum Abi {
33     // NB: This ordering MUST match the AbiDatas array below.
34     // (This is ensured by the test indices_are_correct().)
35
36     // Single platform ABIs come first (`for_arch()` relies on this)
37     Cdecl,
38     Stdcall,
39     Fastcall,
40     Vectorcall,
41     Aapcs,
42     Win64,
43     SysV64,
44
45     // Multiplatform ABIs second
46     Rust,
47     C,
48     System,
49     RustIntrinsic,
50     RustCall,
51     PlatformIntrinsic,
52 }
53
54 #[allow(non_camel_case_types)]
55 #[derive(Copy, Clone, PartialEq, Debug)]
56 pub enum Architecture {
57     X86,
58     X86_64,
59     Arm,
60     Mips,
61     Mipsel
62 }
63
64 #[derive(Copy, Clone)]
65 pub struct AbiData {
66     abi: Abi,
67
68     // Name of this ABI as we like it called.
69     name: &'static str,
70 }
71
72 #[derive(Copy, Clone)]
73 pub enum AbiArchitecture {
74     /// Not a real ABI (e.g., intrinsic)
75     Rust,
76     /// An ABI that specifies cross-platform defaults (e.g., "C")
77     All,
78     /// Multiple architectures (bitset)
79     Archs(u32)
80 }
81
82 #[allow(non_upper_case_globals)]
83 const AbiDatas: &'static [AbiData] = &[
84     // Platform-specific ABIs
85     AbiData {abi: Abi::Cdecl, name: "cdecl" },
86     AbiData {abi: Abi::Stdcall, name: "stdcall" },
87     AbiData {abi: Abi::Fastcall, name: "fastcall" },
88     AbiData {abi: Abi::Vectorcall, name: "vectorcall"},
89     AbiData {abi: Abi::Aapcs, name: "aapcs" },
90     AbiData {abi: Abi::Win64, name: "win64" },
91     AbiData {abi: Abi::SysV64, name: "sysv64" },
92
93     // Cross-platform ABIs
94     //
95     // NB: Do not adjust this ordering without
96     // adjusting the indices below.
97     AbiData {abi: Abi::Rust, name: "Rust" },
98     AbiData {abi: Abi::C, name: "C" },
99     AbiData {abi: Abi::System, name: "system" },
100     AbiData {abi: Abi::RustIntrinsic, name: "rust-intrinsic" },
101     AbiData {abi: Abi::RustCall, name: "rust-call" },
102     AbiData {abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" }
103 ];
104
105 /// Returns the ABI with the given name (if any).
106 pub fn lookup(name: &str) -> Option<Abi> {
107     AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
108 }
109
110 pub fn all_names() -> Vec<&'static str> {
111     AbiDatas.iter().map(|d| d.name).collect()
112 }
113
114 impl Abi {
115     #[inline]
116     pub fn index(&self) -> usize {
117         *self as usize
118     }
119
120     #[inline]
121     pub fn data(&self) -> &'static AbiData {
122         &AbiDatas[self.index()]
123     }
124
125     pub fn name(&self) -> &'static str {
126         self.data().name
127     }
128 }
129
130 impl fmt::Display for Abi {
131     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
132         write!(f, "\"{}\"", self.name())
133     }
134 }
135
136 impl fmt::Display for Os {
137     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138         match *self {
139             Os::Linux => "linux".fmt(f),
140             Os::Windows => "windows".fmt(f),
141             Os::Macos => "macos".fmt(f),
142             Os::iOS => "ios".fmt(f),
143             Os::Android => "android".fmt(f),
144             Os::Freebsd => "freebsd".fmt(f),
145             Os::Dragonfly => "dragonfly".fmt(f),
146             Os::Bitrig => "bitrig".fmt(f),
147             Os::Netbsd => "netbsd".fmt(f),
148             Os::Openbsd => "openbsd".fmt(f),
149             Os::NaCl => "nacl".fmt(f),
150             Os::Haiku => "haiku".fmt(f),
151             Os::Solaris => "solaris".fmt(f),
152         }
153     }
154 }
155
156 #[allow(non_snake_case)]
157 #[test]
158 fn lookup_Rust() {
159     let abi = lookup("Rust");
160     assert!(abi.is_some() && abi.unwrap().data().name == "Rust");
161 }
162
163 #[test]
164 fn lookup_cdecl() {
165     let abi = lookup("cdecl");
166     assert!(abi.is_some() && abi.unwrap().data().name == "cdecl");
167 }
168
169 #[test]
170 fn lookup_baz() {
171     let abi = lookup("baz");
172     assert!(abi.is_none());
173 }
174
175 #[test]
176 fn indices_are_correct() {
177     for (i, abi_data) in AbiDatas.iter().enumerate() {
178         assert_eq!(i, abi_data.abi.index());
179     }
180 }