]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/abi.rs
Auto merge of #36204 - c4rlo:patch-3, r=GuillaumeGomez
[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     Solaris,
28 }
29
30 #[derive(PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
31 pub enum Abi {
32     // NB: This ordering MUST match the AbiDatas array below.
33     // (This is ensured by the test indices_are_correct().)
34
35     // Single platform ABIs come first (`for_arch()` relies on this)
36     Cdecl,
37     Stdcall,
38     Fastcall,
39     Vectorcall,
40     Aapcs,
41     Win64,
42     SysV64,
43
44     // Multiplatform ABIs second
45     Rust,
46     C,
47     System,
48     RustIntrinsic,
49     RustCall,
50     PlatformIntrinsic,
51 }
52
53 #[allow(non_camel_case_types)]
54 #[derive(Copy, Clone, PartialEq, Debug)]
55 pub enum Architecture {
56     X86,
57     X86_64,
58     Arm,
59     Mips,
60     Mipsel
61 }
62
63 #[derive(Copy, Clone)]
64 pub struct AbiData {
65     abi: Abi,
66
67     // Name of this ABI as we like it called.
68     name: &'static str,
69 }
70
71 #[derive(Copy, Clone)]
72 pub enum AbiArchitecture {
73     /// Not a real ABI (e.g., intrinsic)
74     Rust,
75     /// An ABI that specifies cross-platform defaults (e.g., "C")
76     All,
77     /// Multiple architectures (bitset)
78     Archs(u32)
79 }
80
81 #[allow(non_upper_case_globals)]
82 const AbiDatas: &'static [AbiData] = &[
83     // Platform-specific ABIs
84     AbiData {abi: Abi::Cdecl, name: "cdecl" },
85     AbiData {abi: Abi::Stdcall, name: "stdcall" },
86     AbiData {abi: Abi::Fastcall, name: "fastcall" },
87     AbiData {abi: Abi::Vectorcall, name: "vectorcall"},
88     AbiData {abi: Abi::Aapcs, name: "aapcs" },
89     AbiData {abi: Abi::Win64, name: "win64" },
90     AbiData {abi: Abi::SysV64, name: "sysv64" },
91
92     // Cross-platform ABIs
93     //
94     // NB: Do not adjust this ordering without
95     // adjusting the indices below.
96     AbiData {abi: Abi::Rust, name: "Rust" },
97     AbiData {abi: Abi::C, name: "C" },
98     AbiData {abi: Abi::System, name: "system" },
99     AbiData {abi: Abi::RustIntrinsic, name: "rust-intrinsic" },
100     AbiData {abi: Abi::RustCall, name: "rust-call" },
101     AbiData {abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" }
102 ];
103
104 /// Returns the ABI with the given name (if any).
105 pub fn lookup(name: &str) -> Option<Abi> {
106     AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
107 }
108
109 pub fn all_names() -> Vec<&'static str> {
110     AbiDatas.iter().map(|d| d.name).collect()
111 }
112
113 impl Abi {
114     #[inline]
115     pub fn index(&self) -> usize {
116         *self as usize
117     }
118
119     #[inline]
120     pub fn data(&self) -> &'static AbiData {
121         &AbiDatas[self.index()]
122     }
123
124     pub fn name(&self) -> &'static str {
125         self.data().name
126     }
127 }
128
129 impl fmt::Display for Abi {
130     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131         write!(f, "\"{}\"", self.name())
132     }
133 }
134
135 impl fmt::Display for Os {
136     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137         match *self {
138             Os::Linux => "linux".fmt(f),
139             Os::Windows => "windows".fmt(f),
140             Os::Macos => "macos".fmt(f),
141             Os::iOS => "ios".fmt(f),
142             Os::Android => "android".fmt(f),
143             Os::Freebsd => "freebsd".fmt(f),
144             Os::Dragonfly => "dragonfly".fmt(f),
145             Os::Bitrig => "bitrig".fmt(f),
146             Os::Netbsd => "netbsd".fmt(f),
147             Os::Openbsd => "openbsd".fmt(f),
148             Os::NaCl => "nacl".fmt(f),
149             Os::Solaris => "solaris".fmt(f),
150         }
151     }
152 }
153
154 #[allow(non_snake_case)]
155 #[test]
156 fn lookup_Rust() {
157     let abi = lookup("Rust");
158     assert!(abi.is_some() && abi.unwrap().data().name == "Rust");
159 }
160
161 #[test]
162 fn lookup_cdecl() {
163     let abi = lookup("cdecl");
164     assert!(abi.is_some() && abi.unwrap().data().name == "cdecl");
165 }
166
167 #[test]
168 fn lookup_baz() {
169     let abi = lookup("baz");
170     assert!(abi.is_none());
171 }
172
173 #[test]
174 fn indices_are_correct() {
175     for (i, abi_data) in AbiDatas.iter().enumerate() {
176         assert_eq!(i, abi_data.abi.index());
177     }
178 }