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