add a panic-strategy field to the target specification

Now a target can define its panic strategy in its specification. If a
user doesn't specify a panic strategy via the command line, i.e. '-C
panic', then the compiler will use the panic strategy defined by the
target specification.

Custom targets can pick their panic strategy via the "panic-strategy"
field of their target specification JSON file. If omitted in the
specification, the strategy defaults to "unwind".

closes #36647
This commit is contained in:
Jorge Aparicio 2016-09-27 21:26:08 -05:00
parent 49dd95b078
commit cbb967f316
12 changed files with 82 additions and 36 deletions

View file

@ -45,8 +45,36 @@ extern crate libc;
extern crate serialize;
#[macro_use] extern crate log;
extern crate serialize as rustc_serialize; // used by deriving
pub mod tempdir;
pub mod sha2;
pub mod target;
pub mod slice;
pub mod dynamic_lib;
use serialize::json::{Json, ToJson};
#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub enum PanicStrategy {
Unwind,
Abort,
}
impl PanicStrategy {
pub fn desc(&self) -> &str {
match *self {
PanicStrategy::Unwind => "unwind",
PanicStrategy::Abort => "abort",
}
}
}
impl ToJson for PanicStrategy {
fn to_json(&self) -> Json {
match *self {
PanicStrategy::Abort => "abort".to_json(),
PanicStrategy::Unwind => "unwind".to_json(),
}
}
}

View file

@ -50,6 +50,8 @@ use std::default::Default;
use std::io::prelude::*;
use syntax::abi::Abi;
use PanicStrategy;
mod android_base;
mod apple_base;
mod apple_ios_base;
@ -343,6 +345,9 @@ pub struct TargetOptions {
/// Maximum integer size in bits that this target can perform atomic
/// operations on.
pub max_atomic_width: u64,
/// Panic strategy: "unwind" or "abort"
pub panic_strategy: PanicStrategy,
}
impl Default for TargetOptions {
@ -392,6 +397,7 @@ impl Default for TargetOptions {
has_elf_tls: false,
obj_is_bitcode: false,
max_atomic_width: 0,
panic_strategy: PanicStrategy::Unwind,
}
}
}
@ -470,6 +476,19 @@ impl Target {
.map(|o| o.as_u64()
.map(|s| base.options.$key_name = 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("_", "-");
obj.find(&name[..]).map(|o| o.as_array()
@ -530,6 +549,7 @@ impl Target {
key!(has_elf_tls, bool);
key!(obj_is_bitcode, bool);
key!(max_atomic_width, u64);
try!(key!(panic_strategy, PanicStrategy));
Ok(base)
}
@ -672,6 +692,7 @@ 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);
Json::Object(d)
}