]> git.proxmox.com Git - rustc.git/blobdiff - src/librustc_back/target/mod.rs
New upstream version 1.14.0+dfsg1
[rustc.git] / src / librustc_back / target / mod.rs
index 087078021a1883ec98ed0e92f5ea7f62f3c0d357..4d9315a1a3bdb7b556e7e0cb7948dba6c3106329 100644 (file)
@@ -48,11 +48,14 @@ use serialize::json::{Json, ToJson};
 use std::collections::BTreeMap;
 use std::default::Default;
 use std::io::prelude::*;
-use syntax::abi::Abi;
+use syntax::abi::{Abi, lookup as lookup_abi};
+
+use PanicStrategy;
 
 mod android_base;
 mod apple_base;
 mod apple_ios_base;
+mod arm_base;
 mod bitrig_base;
 mod dragonfly_base;
 mod freebsd_base;
@@ -64,11 +67,13 @@ mod netbsd_base;
 mod solaris_base;
 mod windows_base;
 mod windows_msvc_base;
+mod thumb_base;
+mod fuchsia_base;
 
 pub type TargetResult = Result<Target, String>;
 
 macro_rules! supported_targets {
-    ( $(($triple:expr, $module:ident)),+ ) => (
+    ( $(($triple:expr, $module:ident),)+ ) => (
         $(mod $module;)*
 
         /// List of supported targets
@@ -166,12 +171,15 @@ supported_targets! {
     ("x86_64-unknown-netbsd", x86_64_unknown_netbsd),
     ("x86_64-rumprun-netbsd", x86_64_rumprun_netbsd),
 
-    ("i686_unknown_haiku", i686_unknown_haiku),
-    ("x86_64_unknown_haiku", x86_64_unknown_haiku),
+    ("i686-unknown-haiku", i686_unknown_haiku),
+    ("x86_64-unknown-haiku", x86_64_unknown_haiku),
 
     ("x86_64-apple-darwin", x86_64_apple_darwin),
     ("i686-apple-darwin", i686_apple_darwin),
 
+    ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia),
+    ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),
+
     ("i386-apple-ios", i386_apple_ios),
     ("x86_64-apple-ios", x86_64_apple_ios),
     ("aarch64-apple-ios", aarch64_apple_ios),
@@ -188,7 +196,13 @@ supported_targets! {
     ("i586-pc-windows-msvc", i586_pc_windows_msvc),
 
     ("le32-unknown-nacl", le32_unknown_nacl),
-    ("asmjs-unknown-emscripten", asmjs_unknown_emscripten)
+    ("asmjs-unknown-emscripten", asmjs_unknown_emscripten),
+    ("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
+
+    ("thumbv6m-none-eabi", thumbv6m_none_eabi),
+    ("thumbv7m-none-eabi", thumbv7m_none_eabi),
+    ("thumbv7em-none-eabi", thumbv7em_none_eabi),
+    ("thumbv7em-none-eabihf", thumbv7em_none_eabihf),
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
@@ -344,9 +358,15 @@ pub struct TargetOptions {
     // will 'just work'.
     pub obj_is_bitcode: bool,
 
-    /// Maximum integer size in bits that this target can perform atomic
-    /// operations on.
-    pub max_atomic_width: u64,
+    /// Don't use this field; instead use the `.max_atomic_width()` method.
+    pub max_atomic_width: Option<u64>,
+
+    /// Panic strategy: "unwind" or "abort"
+    pub panic_strategy: PanicStrategy,
+
+    /// A blacklist of ABIs unsupported by the current target. Note that generic
+    /// ABIs are considered to be supported on all platforms and cannot be blacklisted.
+    pub abi_blacklist: Vec<Abi>,
 }
 
 impl Default for TargetOptions {
@@ -395,7 +415,9 @@ impl Default for TargetOptions {
             allow_asm: true,
             has_elf_tls: false,
             obj_is_bitcode: false,
-            max_atomic_width: 0,
+            max_atomic_width: None,
+            panic_strategy: PanicStrategy::Unwind,
+            abi_blacklist: vec![],
         }
     }
 }
@@ -415,6 +437,16 @@ impl Target {
         }
     }
 
+    /// Maximum integer size in bits that this target can perform atomic
+    /// operations on.
+    pub fn max_atomic_width(&self) -> u64 {
+        self.options.max_atomic_width.unwrap_or(self.target_pointer_width.parse().unwrap())
+    }
+
+    pub fn is_abi_supported(&self, abi: Abi) -> bool {
+        abi.generic() || !self.options.abi_blacklist.contains(&abi)
+    }
+
     /// Load a target descriptor from a JSON object.
     pub fn from_json(obj: Json) -> TargetResult {
         // While ugly, this code must remain this way to retain
@@ -453,9 +485,6 @@ impl Target {
             options: Default::default(),
         };
 
-        // Default max-atomic-width to target-pointer-width
-        base.options.max_atomic_width = base.target_pointer_width.parse().unwrap();
-
         macro_rules! key {
             ($key_name:ident) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
@@ -468,11 +497,24 @@ impl Target {
                     .map(|o| o.as_boolean()
                          .map(|s| base.options.$key_name = s));
             } );
-            ($key_name:ident, u64) => ( {
+            ($key_name:ident, Option<u64>) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.find(&name[..])
                     .map(|o| o.as_u64()
-                         .map(|s| base.options.$key_name = s));
+                         .map(|s| base.options.$key_name = Some(s)));
+            } );
+            ($key_name:ident, PanicStrategy) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
+                    match s {
+                        "unwind" => base.options.$key_name = PanicStrategy::Unwind,
+                        "abort" => base.options.$key_name = PanicStrategy::Abort,
+                        _ => return Some(Err(format!("'{}' is not a valid value for \
+                                                      panic-strategy. Use 'unwind' or 'abort'.",
+                                                     s))),
+                }
+                Some(Ok(()))
+            })).unwrap_or(Ok(()))
             } );
             ($key_name:ident, list) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
@@ -533,7 +575,24 @@ impl Target {
         key!(exe_allocation_crate);
         key!(has_elf_tls, bool);
         key!(obj_is_bitcode, bool);
-        key!(max_atomic_width, u64);
+        key!(max_atomic_width, Option<u64>);
+        try!(key!(panic_strategy, PanicStrategy));
+
+        if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
+            for name in array.iter().filter_map(|abi| abi.as_string()) {
+                match lookup_abi(name) {
+                    Some(abi) => {
+                        if abi.generic() {
+                            return Err(format!("The ABI \"{}\" is considered to be supported on \
+                                                all targets and cannot be blacklisted", abi))
+                        }
+
+                        base.options.abi_blacklist.push(abi)
+                    }
+                    None => return Err(format!("Unknown ABI \"{}\" in target specification", name))
+                }
+            }
+        }
 
         Ok(base)
     }
@@ -676,6 +735,13 @@ impl ToJson for Target {
         target_option_val!(has_elf_tls);
         target_option_val!(obj_is_bitcode);
         target_option_val!(max_atomic_width);
+        target_option_val!(panic_strategy);
+
+        if default.abi_blacklist != self.options.abi_blacklist {
+            d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
+                .map(Abi::name).map(|name| name.to_json())
+                .collect::<Vec<_>>().to_json());
+        }
 
         Json::Object(d)
     }