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