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;
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
("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),
("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.
// 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 {
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![],
}
}
}
}
}
+ /// 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
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("_", "-");
.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("_", "-");
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)
}
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)
}