Rollup merge of #78875 - petrochenkov:cleantarg, r=Mark-Simulacrum

rustc_target: Further cleanup use of target options

Follow up to https://github.com/rust-lang/rust/pull/77729.

Implements items 2 and 4 from the list in https://github.com/rust-lang/rust/pull/77729#issue-500228243.

The first commit collapses uses of `target.options.foo` into `target.foo`.

The second commit renames some target options to avoid tautology:
`target.target_endian` -> `target.endian`
`target.target_c_int_width` -> `target.c_int_width`
`target.target_os` -> `target.os`
`target.target_env` -> `target.env`
`target.target_vendor` -> `target.vendor`
`target.target_family` -> `target.os_family`
`target.target_mcount` -> `target.mcount`

r? `@Mark-Simulacrum`
This commit is contained in:
Jonas Schievink 2020-11-10 14:45:21 +01:00 committed by GitHub
commit 105f4b8792
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
153 changed files with 452 additions and 502 deletions

View file

@ -39,7 +39,7 @@ use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
use rustc_serialize::json::{Json, ToJson};
use rustc_span::symbol::{sym, Symbol};
use std::collections::BTreeMap;
use std::ops::Deref;
use std::ops::{Deref, DerefMut};
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::{fmt, io};
@ -454,7 +454,7 @@ macro_rules! supported_targets {
$( $($triple)|+ => $module::target(), )+
_ => return None,
};
t.options.is_builtin = true;
t.is_builtin = true;
debug!("got builtin target: {:?}", t);
Some(t)
}
@ -699,21 +699,25 @@ impl HasTargetSpec for Target {
///
/// This has an implementation of `Default`, see each field for what the default is. In general,
/// these try to take "minimal defaults" that don't assume anything about the runtime they run in.
///
/// `TargetOptions` as a separate structure is mostly an implementation detail of `Target`
/// construction, all its fields logically belong to `Target` and available from `Target`
/// through `Deref` impls.
#[derive(PartialEq, Clone, Debug)]
pub struct TargetOptions {
/// Whether the target is built-in or loaded from a custom target specification.
pub is_builtin: bool,
/// String to use as the `target_endian` `cfg` variable. Defaults to "little".
pub target_endian: String,
pub endian: String,
/// Width of c_int type. Defaults to "32".
pub target_c_int_width: String,
pub c_int_width: String,
/// OS name to use for conditional compilation. Defaults to "none".
pub target_os: String,
pub os: String,
/// Environment name to use for conditional compilation. Defaults to "".
pub target_env: String,
pub env: String,
/// Vendor name to use for conditional compilation. Defaults to "unknown".
pub target_vendor: String,
pub vendor: String,
/// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
/// on the command line. Defaults to `LinkerFlavor::Gcc`.
pub linker_flavor: LinkerFlavor,
@ -804,7 +808,7 @@ pub struct TargetOptions {
/// String to append to the name of every static library. Defaults to ".a".
pub staticlib_suffix: String,
/// OS family to use for conditional compilation. Valid options: "unix", "windows".
pub target_family: Option<String>,
pub os_family: Option<String>,
/// Whether the target toolchain's ABI supports returning small structs as an integer.
pub abi_return_struct_as_int: bool,
/// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS,
@ -965,7 +969,7 @@ pub struct TargetOptions {
pub merge_functions: MergeFunctions,
/// Use platform dependent mcount function
pub target_mcount: String,
pub mcount: String,
/// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
pub llvm_abiname: String,
@ -996,11 +1000,11 @@ impl Default for TargetOptions {
fn default() -> TargetOptions {
TargetOptions {
is_builtin: false,
target_endian: "little".to_string(),
target_c_int_width: "32".to_string(),
target_os: "none".to_string(),
target_env: String::new(),
target_vendor: "unknown".to_string(),
endian: "little".to_string(),
c_int_width: "32".to_string(),
os: "none".to_string(),
env: String::new(),
vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
lld_flavor: LldFlavor::Ld,
@ -1024,7 +1028,7 @@ impl Default for TargetOptions {
exe_suffix: String::new(),
staticlib_prefix: "lib".to_string(),
staticlib_suffix: ".a".to_string(),
target_family: None,
os_family: None,
abi_return_struct_as_int: false,
is_like_osx: false,
is_like_solaris: false,
@ -1081,7 +1085,7 @@ impl Default for TargetOptions {
limit_rdylib_exports: true,
override_export_symbols: None,
merge_functions: MergeFunctions::Aliases,
target_mcount: "mcount".to_string(),
mcount: "mcount".to_string(),
llvm_abiname: "".to_string(),
relax_elf_relocations: false,
llvm_args: vec![],
@ -1102,13 +1106,18 @@ impl Deref for Target {
&self.options
}
}
impl DerefMut for Target {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.options
}
}
impl Target {
/// Given a function ABI, turn it into the correct ABI for this target.
pub fn adjust_abi(&self, abi: Abi) -> Abi {
match abi {
Abi::System => {
if self.options.is_like_windows && self.arch == "x86" {
if self.is_like_windows && self.arch == "x86" {
Abi::Stdcall
} else {
Abi::C
@ -1118,7 +1127,7 @@ impl Target {
// See https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
// and the individual pages for __stdcall et al.
Abi::Stdcall | Abi::Fastcall | Abi::Vectorcall | Abi::Thiscall => {
if self.options.is_like_windows && self.arch != "x86" { Abi::C } else { abi }
if self.is_like_windows && self.arch != "x86" { Abi::C } else { abi }
}
Abi::EfiApi => {
if self.arch == "x86_64" {
@ -1134,17 +1143,17 @@ impl Target {
/// Minimum integer size in bits that this target can perform atomic
/// operations on.
pub fn min_atomic_width(&self) -> u64 {
self.options.min_atomic_width.unwrap_or(8)
self.min_atomic_width.unwrap_or(8)
}
/// 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_else(|| self.pointer_width.into())
self.max_atomic_width.unwrap_or_else(|| self.pointer_width.into())
}
pub fn is_abi_supported(&self, abi: Abi) -> bool {
abi.generic() || !self.options.unsupported_abis.contains(&abi)
abi.generic() || !self.unsupported_abis.contains(&abi)
}
/// Loads a target descriptor from a JSON object.
@ -1177,19 +1186,19 @@ impl Target {
($key_name:ident) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.find(&name).and_then(Json::as_string) {
base.options.$key_name = s.to_string();
base.$key_name = s.to_string();
}
} );
($key_name:ident = $json_name:expr) => ( {
let name = $json_name;
if let Some(s) = obj.find(&name).and_then(Json::as_string) {
base.options.$key_name = s.to_string();
base.$key_name = s.to_string();
}
} );
($key_name:ident, bool) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.find(&name).and_then(Json::as_boolean) {
base.options.$key_name = s;
base.$key_name = s;
}
} );
($key_name:ident, Option<u32>) => ( {
@ -1198,20 +1207,20 @@ impl Target {
if s < 1 || s > 5 {
return Err("Not a valid DWARF version number".to_string());
}
base.options.$key_name = Some(s as u32);
base.$key_name = Some(s as u32);
}
} );
($key_name:ident, Option<u64>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.find(&name).and_then(Json::as_u64) {
base.options.$key_name = Some(s);
base.$key_name = Some(s);
}
} );
($key_name:ident, MergeFunctions) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
match s.parse::<MergeFunctions>() {
Ok(mergefunc) => base.options.$key_name = mergefunc,
Ok(mergefunc) => base.$key_name = mergefunc,
_ => return Some(Err(format!("'{}' is not a valid value for \
merge-functions. Use 'disabled', \
'trampolines', or 'aliases'.",
@ -1224,7 +1233,7 @@ impl Target {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
match s.parse::<RelocModel>() {
Ok(relocation_model) => base.options.$key_name = relocation_model,
Ok(relocation_model) => base.$key_name = relocation_model,
_ => return Some(Err(format!("'{}' is not a valid relocation model. \
Run `rustc --print relocation-models` to \
see the list of supported values.", s))),
@ -1236,7 +1245,7 @@ impl Target {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
match s.parse::<CodeModel>() {
Ok(code_model) => base.options.$key_name = Some(code_model),
Ok(code_model) => base.$key_name = Some(code_model),
_ => return Some(Err(format!("'{}' is not a valid code model. \
Run `rustc --print code-models` to \
see the list of supported values.", s))),
@ -1248,7 +1257,7 @@ impl Target {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
match s.parse::<TlsModel>() {
Ok(tls_model) => base.options.$key_name = tls_model,
Ok(tls_model) => base.$key_name = tls_model,
_ => return Some(Err(format!("'{}' is not a valid TLS model. \
Run `rustc --print tls-models` to \
see the list of supported values.", s))),
@ -1260,8 +1269,8 @@ impl Target {
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,
"unwind" => base.$key_name = PanicStrategy::Unwind,
"abort" => base.$key_name = PanicStrategy::Abort,
_ => return Some(Err(format!("'{}' is not a valid value for \
panic-strategy. Use 'unwind' or 'abort'.",
s))),
@ -1273,7 +1282,7 @@ impl Target {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
match s.parse::<RelroLevel>() {
Ok(level) => base.options.$key_name = level,
Ok(level) => base.$key_name = level,
_ => return Some(Err(format!("'{}' is not a valid value for \
relro-level. Use 'full', 'partial, or 'off'.",
s))),
@ -1284,7 +1293,7 @@ impl Target {
($key_name:ident, list) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(v) = obj.find(&name).and_then(Json::as_array) {
base.options.$key_name = v.iter()
base.$key_name = v.iter()
.map(|a| a.as_string().unwrap().to_string())
.collect();
}
@ -1292,7 +1301,7 @@ impl Target {
($key_name:ident, opt_list) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(v) = obj.find(&name).and_then(Json::as_array) {
base.options.$key_name = Some(v.iter()
base.$key_name = Some(v.iter()
.map(|a| a.as_string().unwrap().to_string())
.collect());
}
@ -1300,7 +1309,15 @@ impl Target {
($key_name:ident, optional) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(o) = obj.find(&name[..]) {
base.options.$key_name = o
base.$key_name = o
.as_string()
.map(|s| s.to_string() );
}
} );
($key_name:ident = $json_name:expr, optional) => ( {
let name = $json_name;
if let Some(o) = obj.find(&name[..]) {
base.$key_name = o
.as_string()
.map(|s| s.to_string() );
}
@ -1309,7 +1326,7 @@ impl Target {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
if let Some(flavor) = LldFlavor::from_str(&s) {
base.options.$key_name = flavor;
base.$key_name = flavor;
} else {
return Some(Err(format!(
"'{}' is not a valid value for lld-flavor. \
@ -1323,7 +1340,7 @@ impl Target {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
match LinkerFlavor::from_str(s) {
Some(linker_flavor) => base.options.$key_name = linker_flavor,
Some(linker_flavor) => base.$key_name = linker_flavor,
_ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \
Use {}", s, LinkerFlavor::one_of()))),
}
@ -1334,7 +1351,7 @@ impl Target {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
match s.parse::<CrtObjectsFallback>() {
Ok(fallback) => base.options.$key_name = Some(fallback),
Ok(fallback) => base.$key_name = Some(fallback),
_ => return Some(Err(format!("'{}' is not a valid CRT objects fallback. \
Use 'musl', 'mingw' or 'wasm'", s))),
}
@ -1366,7 +1383,7 @@ impl Target {
args.insert(kind, v);
}
base.options.$key_name = args;
base.$key_name = args;
}
} );
($key_name:ident, link_args) => ( {
@ -1393,7 +1410,7 @@ impl Target {
args.insert(flavor, v);
}
base.options.$key_name = args;
base.$key_name = args;
}
} );
($key_name:ident, env) => ( {
@ -1405,7 +1422,7 @@ impl Target {
if p.len() == 2 {
let k = p[0].to_string();
let v = p[1].to_string();
base.options.$key_name.push((k, v));
base.$key_name.push((k, v));
}
}
}
@ -1414,11 +1431,11 @@ impl Target {
}
key!(is_builtin, bool);
key!(target_endian);
key!(target_c_int_width);
key!(target_os = "os");
key!(target_env = "env");
key!(target_vendor = "vendor");
key!(endian = "target_endian");
key!(c_int_width = "target_c_int_width");
key!(os);
key!(env);
key!(vendor);
key!(linker_flavor, LinkerFlavor)?;
key!(linker, optional);
key!(lld_flavor, LldFlavor)?;
@ -1452,7 +1469,7 @@ impl Target {
key!(exe_suffix);
key!(staticlib_prefix);
key!(staticlib_suffix);
key!(target_family, optional);
key!(os_family = "target_family", optional);
key!(abi_return_struct_as_int, bool);
key!(is_like_osx, bool);
key!(is_like_solaris, bool);
@ -1498,7 +1515,7 @@ impl Target {
key!(limit_rdylib_exports, bool);
key!(override_export_symbols, opt_list);
key!(merge_functions, MergeFunctions)?;
key!(target_mcount);
key!(mcount = "target_mcount");
key!(llvm_abiname);
key!(relax_elf_relocations, bool);
key!(llvm_args, list);
@ -1521,7 +1538,7 @@ impl Target {
));
}
base.options.unsupported_abis.push(abi)
base.unsupported_abis.push(abi)
}
None => {
return Err(format!(
@ -1610,21 +1627,20 @@ impl ToJson for Target {
macro_rules! target_option_val {
($attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
if default.$attr != self.options.$attr {
d.insert(name, self.options.$attr.to_json());
if default.$attr != self.$attr {
d.insert(name, self.$attr.to_json());
}
}};
($attr:ident, $key_name:expr) => {{
let name = $key_name;
if default.$attr != self.options.$attr {
d.insert(name.to_string(), self.options.$attr.to_json());
if default.$attr != self.$attr {
d.insert(name.to_string(), self.$attr.to_json());
}
}};
(link_args - $attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
if default.$attr != self.options.$attr {
if default.$attr != self.$attr {
let obj = self
.options
.$attr
.iter()
.map(|(k, v)| (k.desc().to_owned(), v.clone()))
@ -1634,9 +1650,8 @@ impl ToJson for Target {
}};
(env - $attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
if default.$attr != self.options.$attr {
if default.$attr != self.$attr {
let obj = self
.options
.$attr
.iter()
.map(|&(ref k, ref v)| k.clone() + "=" + &v)
@ -1652,11 +1667,11 @@ impl ToJson for Target {
target_val!(data_layout);
target_option_val!(is_builtin);
target_option_val!(target_endian);
target_option_val!(target_c_int_width);
target_option_val!(target_os, "os");
target_option_val!(target_env, "env");
target_option_val!(target_vendor, "vendor");
target_option_val!(endian, "target_endian");
target_option_val!(c_int_width, "target_c_int_width");
target_option_val!(os);
target_option_val!(env);
target_option_val!(vendor);
target_option_val!(linker_flavor);
target_option_val!(linker);
target_option_val!(lld_flavor);
@ -1690,7 +1705,7 @@ impl ToJson for Target {
target_option_val!(exe_suffix);
target_option_val!(staticlib_prefix);
target_option_val!(staticlib_suffix);
target_option_val!(target_family);
target_option_val!(os_family, "target_family");
target_option_val!(abi_return_struct_as_int);
target_option_val!(is_like_osx);
target_option_val!(is_like_solaris);
@ -1736,7 +1751,7 @@ impl ToJson for Target {
target_option_val!(limit_rdylib_exports);
target_option_val!(override_export_symbols);
target_option_val!(merge_functions);
target_option_val!(target_mcount);
target_option_val!(mcount, "target_mcount");
target_option_val!(llvm_abiname);
target_option_val!(relax_elf_relocations);
target_option_val!(llvm_args);
@ -1744,11 +1759,10 @@ impl ToJson for Target {
target_option_val!(eh_frame_header);
target_option_val!(has_thumb_interworking);
if default.unsupported_abis != self.options.unsupported_abis {
if default.unsupported_abis != self.unsupported_abis {
d.insert(
"unsupported-abis".to_string(),
self.options
.unsupported_abis
self.unsupported_abis
.iter()
.map(|&name| Abi::name(name).to_json())
.collect::<Vec<_>>()