diff --git a/src/Cargo.lock b/src/Cargo.lock index b265ee5765afa..e14b9da971301 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1728,10 +1728,10 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", "rustc_apfloat 0.0.0", - "rustc_back 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_target 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", @@ -1818,8 +1818,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "rustc-main" version = "0.0.0" dependencies = [ - "rustc_back 0.0.0", "rustc_driver 0.0.0", + "rustc_target 0.0.0", ] [[package]] @@ -1833,6 +1833,7 @@ version = "0.0.0" dependencies = [ "rustc 0.0.0", "rustc_errors 0.0.0", + "rustc_target 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] @@ -1857,16 +1858,6 @@ dependencies = [ "core 0.0.0", ] -[[package]] -name = "rustc_back" -version = "0.0.0" -dependencies = [ - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serialize 0.0.0", - "syntax 0.0.0", -] - [[package]] name = "rustc_borrowck" version = "0.0.0" @@ -1895,6 +1886,7 @@ name = "rustc_cratesio_shim" version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1906,6 +1898,7 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_cratesio_shim 0.0.0", "serialize 0.0.0", "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1921,7 +1914,6 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_allocator 0.0.0", - "rustc_back 0.0.0", "rustc_borrowck 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", @@ -1934,6 +1926,7 @@ dependencies = [ "rustc_privacy 0.0.0", "rustc_resolve 0.0.0", "rustc_save_analysis 0.0.0", + "rustc_target 0.0.0", "rustc_traits 0.0.0", "rustc_trans_utils 0.0.0", "rustc_typeck 0.0.0", @@ -1976,6 +1969,7 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_mir 0.0.0", + "rustc_target 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] @@ -2011,9 +2005,9 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", "rustc 0.0.0", - "rustc_back 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_target 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_ext 0.0.0", @@ -2032,10 +2026,10 @@ dependencies = [ "log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_apfloat 0.0.0", - "rustc_back 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_target 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", @@ -2116,11 +2110,22 @@ dependencies = [ "rustc 0.0.0", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_data_structures 0.0.0", + "rustc_target 0.0.0", "rustc_typeck 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] +[[package]] +name = "rustc_target" +version = "0.0.0" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_cratesio_shim 0.0.0", + "serialize 0.0.0", +] + [[package]] name = "rustc_traits" version = "0.0.0" @@ -2138,7 +2143,6 @@ dependencies = [ name = "rustc_trans" version = "0.0.0" dependencies = [ - "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2150,7 +2154,6 @@ dependencies = [ "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_allocator 0.0.0", "rustc_apfloat 0.0.0", - "rustc_back 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", @@ -2158,6 +2161,7 @@ dependencies = [ "rustc_llvm 0.0.0", "rustc_mir 0.0.0", "rustc_platform_intrinsics 0.0.0", + "rustc_target 0.0.0", "rustc_trans_utils 0.0.0", "serialize 0.0.0", "syntax 0.0.0", @@ -2173,10 +2177,10 @@ dependencies = [ "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", - "rustc_back 0.0.0", "rustc_data_structures 0.0.0", "rustc_incremental 0.0.0", "rustc_mir 0.0.0", + "rustc_target 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] @@ -2205,6 +2209,7 @@ dependencies = [ "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", "rustc_platform_intrinsics 0.0.0", + "rustc_target 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] @@ -2543,9 +2548,9 @@ version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_cratesio_shim 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_target 0.0.0", "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "syntax_pos 0.0.0", @@ -2559,6 +2564,7 @@ dependencies = [ "proc_macro 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_target 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 2aae0f24d4849..357ebb89fb652 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -18,7 +18,7 @@ lazy_static = "1.0.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } proc_macro = { path = "../libproc_macro" } rustc_apfloat = { path = "../librustc_apfloat" } -rustc_back = { path = "../librustc_back" } +rustc_target = { path = "../librustc_target" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index be9f8b8dac5c0..62f3f9f4486ad 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -41,7 +41,7 @@ //! This order consistency is required in a few places in rustc, for //! example generator inference, and possibly also HIR borrowck. -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute}; use syntax_pos::Span; use hir::*; diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 1eaacdb1d7ff3..362c0bf07f73b 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -25,7 +25,7 @@ use hir as ast; use hir::map::{self, Node}; use hir::{Expr, FnDecl}; use hir::intravisit::FnKind; -use syntax::abi; +use rustc_target::spec::abi; use syntax::ast::{Attribute, Name, NodeId}; use syntax_pos::Span; diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 9520ed32af9e1..a9613a60a57c0 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -21,7 +21,7 @@ use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace}; use middle::cstore::CrateStore; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID}; use syntax::codemap::Spanned; use syntax::ext::base::MacroKind; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f471ffb072d67..0dc89d64bd501 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -34,7 +34,7 @@ use mir::mono::Linkage; use syntax_pos::{Span, DUMMY_SP}; use syntax::codemap::{self, Spanned}; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; use syntax::attr::InlineAttr; diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index d3f2458ef87c7..3943c30127d6f 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -10,7 +10,7 @@ pub use self::AnnNode::*; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::codemap::{CodeMap, Spanned}; use syntax::parse::{token, ParseSess}; diff --git a/src/librustc/ich/impls_misc.rs b/src/librustc/ich/impls_misc.rs index 951315fb4a849..db40417917547 100644 --- a/src/librustc/ich/impls_misc.rs +++ b/src/librustc/ich/impls_misc.rs @@ -20,7 +20,7 @@ impl_stable_hash_for!(enum ::session::search_paths::PathKind { All }); -impl_stable_hash_for!(enum ::rustc_back::PanicStrategy { +impl_stable_hash_for!(enum ::rustc_target::spec::PanicStrategy { Abort, Unwind }); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 4ac678aaa052d..d7e16ab36205e 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -82,7 +82,7 @@ impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind { }); -impl_stable_hash_for!(enum ::syntax::abi::Abi { +impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi { Cdecl, Stdcall, Fastcall, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index bb495049483ac..f85d0a9bf0c2e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -81,7 +81,7 @@ extern crate graphviz; #[macro_use] extern crate lazy_static; #[cfg(windows)] extern crate libc; -extern crate rustc_back; +extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; extern crate serialize; extern crate rustc_const_math; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index d5849ea22b1ef..f90baa2ccd95d 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -657,7 +657,8 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { } } -impl<'a, 'tcx> LayoutOf> for &'a LateContext<'a, 'tcx> { +impl<'a, 'tcx> LayoutOf for &'a LateContext<'a, 'tcx> { + type Ty = Ty<'tcx>; type TyLayout = Result, LayoutError<'tcx>>; fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 60e197e614aa6..4400ebc294fd8 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -37,7 +37,7 @@ use syntax::ast; use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; use syntax_pos::Span; -use rustc_back::target::Target; +use rustc_target::spec::Target; use rustc_data_structures::sync::{MetadataRef, Lrc}; pub use self::NativeLibraryKind::*; diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index e7fc8d633c82f..4996a6acff85c 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -69,7 +69,7 @@ use ty::TyCtxt; use middle::cstore::{self, DepKind}; use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic}; use util::nodemap::FxHashMap; -use rustc_back::PanicStrategy; +use rustc_target::spec::PanicStrategy; /// A list of dependencies for a certain crate type. /// diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 0a4e5094cde77..27f7dbf508db0 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -13,7 +13,7 @@ use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use ty::layout::{LayoutError, Pointer, SizeSkeleton}; -use syntax::abi::Abi::RustIntrinsic; +use rustc_target::spec::abi::Abi::RustIntrinsic; use syntax_pos::Span; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 48a62c8c14d69..0aeb15b49fbbd 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -26,7 +26,7 @@ use middle::privacy; use session::config; use util::nodemap::{NodeSet, FxHashSet}; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr; use hir; diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index a2bceb1910221..42e4d3861bae3 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -13,7 +13,7 @@ use session::config; use middle::lang_items; -use rustc_back::PanicStrategy; +use rustc_target::spec::PanicStrategy; use syntax::ast; use syntax::symbol::Symbol; use syntax_pos::Span; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 456e83f4700e4..ab703d423c61d 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -22,8 +22,8 @@ use session::{early_error, early_warn, Session}; use session::search_paths::SearchPaths; use ich::StableHashingContext; -use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; -use rustc_back::target::{Target, TargetTriple}; +use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; +use rustc_target::spec::{Target, TargetTriple}; use rustc_data_structures::stable_hasher::ToStableHashKey; use lint; use middle::cstore; @@ -770,7 +770,7 @@ macro_rules! options { pub const parse_sanitizer: Option<&'static str> = Some("one of: `address`, `leak`, `memory` or `thread`"); pub const parse_linker_flavor: Option<&'static str> = - Some(::rustc_back::LinkerFlavor::one_of()); + Some(::rustc_target::spec::LinkerFlavor::one_of()); pub const parse_optimization_fuel: Option<&'static str> = Some("crate=integer"); pub const parse_unpretty: Option<&'static str> = @@ -782,7 +782,7 @@ macro_rules! options { #[allow(dead_code)] mod $mod_set { use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto}; - use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; + use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; use std::path::PathBuf; $( @@ -2323,8 +2323,7 @@ mod dep_tracking { use super::{CrateType, DebugInfoLevel, ErrorOutputType, Lto, OptLevel, OutputTypes, Passes, Sanitizer}; use syntax::feature_gate::UnstableFeatures; - use rustc_back::{PanicStrategy, RelroLevel}; - use rustc_back::target::TargetTriple; + use rustc_target::spec::{PanicStrategy, RelroLevel, TargetTriple}; use syntax::edition::Edition; pub trait DepTrackingHash { @@ -2456,7 +2455,7 @@ mod tests { use std::iter::FromIterator; use std::path::PathBuf; use super::{Externs, OutputType, OutputTypes}; - use rustc_back::{PanicStrategy, RelroLevel}; + use rustc_target::spec::{PanicStrategy, RelroLevel}; use syntax::symbol::Symbol; use syntax::edition::{Edition, DEFAULT_EDITION}; use syntax; diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3bd2bb3c8beb0..a0f1144342532 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -41,8 +41,8 @@ use syntax::{ast, codemap}; use syntax::feature_gate::AttributeType; use syntax_pos::{MultiSpan, Span}; -use rustc_back::{LinkerFlavor, PanicStrategy}; -use rustc_back::target::{Target, TargetTriple}; +use rustc_target::spec::{LinkerFlavor, PanicStrategy}; +use rustc_target::spec::{Target, TargetTriple}; use rustc_data_structures::flock; use jobserver::Client; diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index a7669b942e3b0..33abc0c7e15aa 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1091,7 +1091,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })), false, hir::Unsafety::Normal, - ::syntax::abi::Abi::Rust + ::rustc_target::spec::abi::Abi::Rust ) } else { tcx.mk_fn_sig( @@ -1099,7 +1099,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })), false, hir::Unsafety::Normal, - ::syntax::abi::Abi::Rust + ::rustc_target::spec::abi::Abi::Rust ) }; format!("{}", ty::Binder::bind(sig)) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index cfc14b7bfe461..f43f5cf3e3ff4 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -51,7 +51,7 @@ use std::cmp; use std::fmt; use std::mem; use std::rc::Rc; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use hir; use util::nodemap::{FxHashMap, FxHashSet}; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c35f515a99e43..4f49b159ad387 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -70,7 +70,7 @@ use std::ops::Deref; use std::iter; use std::sync::mpsc; use std::sync::Arc; -use syntax::abi; +use rustc_target::spec::abi; use syntax::ast::{self, NodeId}; use syntax::attr; use syntax::codemap::MultiSpan; @@ -1204,7 +1204,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { f: F) -> R where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R { - let data_layout = TargetDataLayout::parse(s); + let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| { + s.fatal(&err); + }); let interners = CtxtInterners::new(&arenas.interner); let common_types = CommonTypes::new(&interners); let dep_graph = hir.dep_graph.clone(); diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index eb3924186472c..cf2004a681e62 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -11,7 +11,7 @@ use hir::def_id::DefId; use ty::{self, BoundRegion, Region, Ty, TyCtxt}; use std::fmt; -use syntax::abi; +use rustc_target::spec::abi; use syntax::ast; use errors::DiagnosticBuilder; use syntax_pos::Span; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 02a03bc542a3a..ecd415c4bc420 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -12,7 +12,7 @@ use hir::def_id::DefId; use ty::{self, Ty, TypeFoldable, Substs, TyCtxt}; use ty::subst::Kind; use traits; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use util::ppaux; use std::fmt; diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 77e2e9447f1ed..942cfdb36b8da 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -8,10 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::Integer::*; -pub use self::Primitive::*; - -use session::{self, DataTypeKind, Session}; +use session::{self, DataTypeKind}; use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions}; use syntax::ast::{self, FloatTy, IntTy, UintTy}; @@ -21,432 +18,28 @@ use syntax_pos::DUMMY_SP; use std::cmp; use std::fmt; use std::i128; -use std::iter; use std::mem; -use std::ops::{Add, Sub, Mul, AddAssign, Deref, RangeInclusive}; +use std::ops::RangeInclusive; use ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; -/// Parsed [Data layout](http://llvm.org/docs/LangRef.html#data-layout) -/// for a target, which contains everything needed to compute layouts. -pub struct TargetDataLayout { - pub endian: Endian, - pub i1_align: Align, - pub i8_align: Align, - pub i16_align: Align, - pub i32_align: Align, - pub i64_align: Align, - pub i128_align: Align, - pub f32_align: Align, - pub f64_align: Align, - pub pointer_size: Size, - pub pointer_align: Align, - pub aggregate_align: Align, - - /// Alignments for vector types. - pub vector_align: Vec<(Size, Align)> -} - -impl Default for TargetDataLayout { - /// Creates an instance of `TargetDataLayout`. - fn default() -> TargetDataLayout { - TargetDataLayout { - endian: Endian::Big, - i1_align: Align::from_bits(8, 8).unwrap(), - i8_align: Align::from_bits(8, 8).unwrap(), - i16_align: Align::from_bits(16, 16).unwrap(), - i32_align: Align::from_bits(32, 32).unwrap(), - i64_align: Align::from_bits(32, 64).unwrap(), - i128_align: Align::from_bits(32, 64).unwrap(), - f32_align: Align::from_bits(32, 32).unwrap(), - f64_align: Align::from_bits(64, 64).unwrap(), - pointer_size: Size::from_bits(64), - pointer_align: Align::from_bits(64, 64).unwrap(), - aggregate_align: Align::from_bits(0, 64).unwrap(), - vector_align: vec![ - (Size::from_bits(64), Align::from_bits(64, 64).unwrap()), - (Size::from_bits(128), Align::from_bits(128, 128).unwrap()) - ] - } - } -} - -impl TargetDataLayout { - pub fn parse(sess: &Session) -> TargetDataLayout { - // Parse a bit count from a string. - let parse_bits = |s: &str, kind: &str, cause: &str| { - s.parse::().unwrap_or_else(|err| { - sess.err(&format!("invalid {} `{}` for `{}` in \"data-layout\": {}", - kind, s, cause, err)); - 0 - }) - }; - - // Parse a size string. - let size = |s: &str, cause: &str| { - Size::from_bits(parse_bits(s, "size", cause)) - }; - - // Parse an alignment string. - let align = |s: &[&str], cause: &str| { - if s.is_empty() { - sess.err(&format!("missing alignment for `{}` in \"data-layout\"", cause)); - } - let abi = parse_bits(s[0], "alignment", cause); - let pref = s.get(1).map_or(abi, |pref| parse_bits(pref, "alignment", cause)); - Align::from_bits(abi, pref).unwrap_or_else(|err| { - sess.err(&format!("invalid alignment for `{}` in \"data-layout\": {}", - cause, err)); - Align::from_bits(8, 8).unwrap() - }) - }; - - let mut dl = TargetDataLayout::default(); - let mut i128_align_src = 64; - for spec in sess.target.target.data_layout.split("-") { - match &spec.split(":").collect::>()[..] { - &["e"] => dl.endian = Endian::Little, - &["E"] => dl.endian = Endian::Big, - &["a", ref a..] => dl.aggregate_align = align(a, "a"), - &["f32", ref a..] => dl.f32_align = align(a, "f32"), - &["f64", ref a..] => dl.f64_align = align(a, "f64"), - &[p @ "p", s, ref a..] | &[p @ "p0", s, ref a..] => { - dl.pointer_size = size(s, p); - dl.pointer_align = align(a, p); - } - &[s, ref a..] if s.starts_with("i") => { - let bits = match s[1..].parse::() { - Ok(bits) => bits, - Err(_) => { - size(&s[1..], "i"); // For the user error. - continue; - } - }; - let a = align(a, s); - match bits { - 1 => dl.i1_align = a, - 8 => dl.i8_align = a, - 16 => dl.i16_align = a, - 32 => dl.i32_align = a, - 64 => dl.i64_align = a, - _ => {} - } - if bits >= i128_align_src && bits <= 128 { - // Default alignment for i128 is decided by taking the alignment of - // largest-sized i{64...128}. - i128_align_src = bits; - dl.i128_align = a; - } - } - &[s, ref a..] if s.starts_with("v") => { - let v_size = size(&s[1..], "v"); - let a = align(a, s); - if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) { - v.1 = a; - continue; - } - // No existing entry, add a new one. - dl.vector_align.push((v_size, a)); - } - _ => {} // Ignore everything else. - } - } - - // Perform consistency checks against the Target information. - let endian_str = match dl.endian { - Endian::Little => "little", - Endian::Big => "big" - }; - if endian_str != sess.target.target.target_endian { - sess.err(&format!("inconsistent target specification: \"data-layout\" claims \ - architecture is {}-endian, while \"target-endian\" is `{}`", - endian_str, sess.target.target.target_endian)); - } - - if dl.pointer_size.bits().to_string() != sess.target.target.target_pointer_width { - sess.err(&format!("inconsistent target specification: \"data-layout\" claims \ - pointers are {}-bit, while \"target-pointer-width\" is `{}`", - dl.pointer_size.bits(), sess.target.target.target_pointer_width)); - } - - dl - } - - /// Return exclusive upper bound on object size. - /// - /// The theoretical maximum object size is defined as the maximum positive `isize` value. - /// This ensures that the `offset` semantics remain well-defined by allowing it to correctly - /// index every address within an object along with one byte past the end, along with allowing - /// `isize` to store the difference between any two pointers into an object. - /// - /// The upper bound on 64-bit currently needs to be lower because LLVM uses a 64-bit integer - /// to represent object size in bits. It would need to be 1 << 61 to account for this, but is - /// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable - /// address space on 64-bit ARMv8 and x86_64. - pub fn obj_size_bound(&self) -> u64 { - match self.pointer_size.bits() { - 16 => 1 << 15, - 32 => 1 << 31, - 64 => 1 << 47, - bits => bug!("obj_size_bound: unknown pointer bit size {}", bits) - } - } - - pub fn ptr_sized_integer(&self) -> Integer { - match self.pointer_size.bits() { - 16 => I16, - 32 => I32, - 64 => I64, - bits => bug!("ptr_sized_integer: unknown pointer bit size {}", bits) - } - } - - pub fn vector_align(&self, vec_size: Size) -> Align { - for &(size, align) in &self.vector_align { - if size == vec_size { - return align; - } - } - // Default to natural alignment, which is what LLVM does. - // That is, use the size, rounded up to a power of 2. - let align = vec_size.bytes().next_power_of_two(); - Align::from_bytes(align, align).unwrap() - } -} - -pub trait HasDataLayout: Copy { - fn data_layout(&self) -> &TargetDataLayout; -} - -impl<'a> HasDataLayout for &'a TargetDataLayout { - fn data_layout(&self) -> &TargetDataLayout { - self - } -} - -/// Endianness of the target, which must match cfg(target-endian). -#[derive(Copy, Clone)] -pub enum Endian { - Little, - Big -} - -/// Size of a type in bytes. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct Size { - raw: u64 -} - -impl Size { - pub fn from_bits(bits: u64) -> Size { - // Avoid potential overflow from `bits + 7`. - Size::from_bytes(bits / 8 + ((bits % 8) + 7) / 8) - } - - pub fn from_bytes(bytes: u64) -> Size { - if bytes >= (1 << 61) { - bug!("Size::from_bytes: {} bytes in bits doesn't fit in u64", bytes) - } - Size { - raw: bytes - } - } - - pub fn bytes(self) -> u64 { - self.raw - } - - pub fn bits(self) -> u64 { - self.bytes() * 8 - } - - pub fn abi_align(self, align: Align) -> Size { - let mask = align.abi() - 1; - Size::from_bytes((self.bytes() + mask) & !mask) - } - - pub fn is_abi_aligned(self, align: Align) -> bool { - let mask = align.abi() - 1; - self.bytes() & mask == 0 - } - - pub fn checked_add(self, offset: Size, cx: C) -> Option { - let dl = cx.data_layout(); - - // Each Size is less than dl.obj_size_bound(), so the sum is - // also less than 1 << 62 (and therefore can't overflow). - let bytes = self.bytes() + offset.bytes(); - - if bytes < dl.obj_size_bound() { - Some(Size::from_bytes(bytes)) - } else { - None - } - } - - pub fn checked_mul(self, count: u64, cx: C) -> Option { - let dl = cx.data_layout(); - - match self.bytes().checked_mul(count) { - Some(bytes) if bytes < dl.obj_size_bound() => { - Some(Size::from_bytes(bytes)) - } - _ => None - } - } -} - -// Panicking addition, subtraction and multiplication for convenience. -// Avoid during layout computation, return `LayoutError` instead. - -impl Add for Size { - type Output = Size; - fn add(self, other: Size) -> Size { - // Each Size is less than 1 << 61, so the sum is - // less than 1 << 62 (and therefore can't overflow). - Size::from_bytes(self.bytes() + other.bytes()) - } -} - -impl Sub for Size { - type Output = Size; - fn sub(self, other: Size) -> Size { - // Each Size is less than 1 << 61, so an underflow - // would result in a value larger than 1 << 61, - // which Size::from_bytes will catch for us. - Size::from_bytes(self.bytes() - other.bytes()) - } -} - -impl Mul for Size { - type Output = Size; - fn mul(self, count: u64) -> Size { - match self.bytes().checked_mul(count) { - Some(bytes) => Size::from_bytes(bytes), - None => { - bug!("Size::mul: {} * {} doesn't fit in u64", self.bytes(), count) - } - } - } -} - -impl AddAssign for Size { - fn add_assign(&mut self, other: Size) { - *self = *self + other; - } -} - -/// Alignment of a type in bytes, both ABI-mandated and preferred. -/// Each field is a power of two, giving the alignment a maximum -/// value of 2(28 - 1), which is limited by LLVM to a i32, with -/// a maximum capacity of 231 - 1 or 2147483647. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] -pub struct Align { - abi_pow2: u8, - pref_pow2: u8, -} +pub use rustc_target::abi::*; -impl Align { - pub fn from_bits(abi: u64, pref: u64) -> Result { - Align::from_bytes(Size::from_bits(abi).bytes(), - Size::from_bits(pref).bytes()) - } - - pub fn from_bytes(abi: u64, pref: u64) -> Result { - let log2 = |align: u64| { - // Treat an alignment of 0 bytes like 1-byte alignment. - if align == 0 { - return Ok(0); - } - - let mut bytes = align; - let mut pow: u8 = 0; - while (bytes & 1) == 0 { - pow += 1; - bytes >>= 1; - } - if bytes != 1 { - Err(format!("`{}` is not a power of 2", align)) - } else if pow > 30 { - Err(format!("`{}` is too large", align)) - } else { - Ok(pow) - } - }; - - Ok(Align { - abi_pow2: log2(abi)?, - pref_pow2: log2(pref)?, - }) - } - - pub fn abi(self) -> u64 { - 1 << self.abi_pow2 - } - - pub fn pref(self) -> u64 { - 1 << self.pref_pow2 - } - - pub fn abi_bits(self) -> u64 { - self.abi() * 8 - } - - pub fn pref_bits(self) -> u64 { - self.pref() * 8 - } - - pub fn min(self, other: Align) -> Align { - Align { - abi_pow2: cmp::min(self.abi_pow2, other.abi_pow2), - pref_pow2: cmp::min(self.pref_pow2, other.pref_pow2), - } - } - - pub fn max(self, other: Align) -> Align { - Align { - abi_pow2: cmp::max(self.abi_pow2, other.abi_pow2), - pref_pow2: cmp::max(self.pref_pow2, other.pref_pow2), - } - } -} - -/// Integers, also used for enum discriminants. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub enum Integer { - I8, - I16, - I32, - I64, - I128, +pub trait IntegerExt { + fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, signed: bool) -> Ty<'tcx>; + fn from_attr(cx: C, ity: attr::IntType) -> Integer; + fn repr_discr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: Ty<'tcx>, + repr: &ReprOptions, + min: i128, + max: i128) + -> (Integer, bool); } -impl<'a, 'tcx> Integer { - pub fn size(&self) -> Size { - match *self { - I8 => Size::from_bytes(1), - I16 => Size::from_bytes(2), - I32 => Size::from_bytes(4), - I64 => Size::from_bytes(8), - I128 => Size::from_bytes(16), - } - } - - pub fn align(&self, cx: C) -> Align { - let dl = cx.data_layout(); - - match *self { - I8 => dl.i8_align, - I16 => dl.i16_align, - I32 => dl.i32_align, - I64 => dl.i64_align, - I128 => dl.i128_align, - } - } - - pub fn to_ty(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, signed: bool) -> Ty<'tcx> { +impl IntegerExt for Integer { + fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, signed: bool) -> Ty<'tcx> { match (*self, signed) { (I8, false) => tcx.types.u8, (I16, false) => tcx.types.u16, @@ -461,57 +54,8 @@ impl<'a, 'tcx> Integer { } } - /// Find the smallest Integer type which can represent the signed value. - pub fn fit_signed(x: i128) -> Integer { - match x { - -0x0000_0000_0000_0080...0x0000_0000_0000_007f => I8, - -0x0000_0000_0000_8000...0x0000_0000_0000_7fff => I16, - -0x0000_0000_8000_0000...0x0000_0000_7fff_ffff => I32, - -0x8000_0000_0000_0000...0x7fff_ffff_ffff_ffff => I64, - _ => I128 - } - } - - /// Find the smallest Integer type which can represent the unsigned value. - pub fn fit_unsigned(x: u128) -> Integer { - match x { - 0...0x0000_0000_0000_00ff => I8, - 0...0x0000_0000_0000_ffff => I16, - 0...0x0000_0000_ffff_ffff => I32, - 0...0xffff_ffff_ffff_ffff => I64, - _ => I128, - } - } - - /// Find the smallest integer with the given alignment. - pub fn for_abi_align(cx: C, align: Align) -> Option { - let dl = cx.data_layout(); - - let wanted = align.abi(); - for &candidate in &[I8, I16, I32, I64, I128] { - if wanted == candidate.align(dl).abi() && wanted == candidate.size().bytes() { - return Some(candidate); - } - } - None - } - - /// Find the largest integer with the given alignment or less. - pub fn approximate_abi_align(cx: C, align: Align) -> Integer { - let dl = cx.data_layout(); - - let wanted = align.abi(); - // FIXME(eddyb) maybe include I128 in the future, when it works everywhere. - for &candidate in &[I64, I32, I16] { - if wanted >= candidate.align(dl).abi() && wanted >= candidate.size().bytes() { - return candidate; - } - } - I8 - } - /// Get the Integer type from an attr::IntType. - pub fn from_attr(cx: C, ity: attr::IntType) -> Integer { + fn from_attr(cx: C, ity: attr::IntType) -> Integer { let dl = cx.data_layout(); match ity { @@ -530,7 +74,7 @@ impl<'a, 'tcx> Integer { /// signed discriminant range and #[repr] attribute. /// N.B.: u128 values above i128::MAX will be treated as signed, but /// that shouldn't affect anything, other than maybe debuginfo. - fn repr_discr(tcx: TyCtxt<'a, 'tcx, 'tcx>, + fn repr_discr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>, repr: &ReprOptions, min: i128, @@ -578,46 +122,12 @@ impl<'a, 'tcx> Integer { } } -/// Fundamental unit of memory access and layout. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub enum Primitive { - /// The `bool` is the signedness of the `Integer` type. - /// - /// One would think we would not care about such details this low down, - /// but some ABIs are described in terms of C types and ISAs where the - /// integer arithmetic is done on {sign,zero}-extended registers, e.g. - /// a negative integer passed by zero-extension will appear positive in - /// the callee, and most operations on it will produce the wrong values. - Int(Integer, bool), - F32, - F64, - Pointer +pub trait PrimitiveExt { + fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx>; } -impl<'a, 'tcx> Primitive { - pub fn size(self, cx: C) -> Size { - let dl = cx.data_layout(); - - match self { - Int(i, _) => i.size(), - F32 => Size::from_bits(32), - F64 => Size::from_bits(64), - Pointer => dl.pointer_size - } - } - - pub fn align(self, cx: C) -> Align { - let dl = cx.data_layout(); - - match self { - Int(i, _) => i.align(dl), - F32 => dl.f32_align, - F64 => dl.f64_align, - Pointer => dl.pointer_align - } - } - - pub fn to_ty(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { +impl PrimitiveExt for Primitive { + fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { match *self { Int(i, signed) => i.to_ty(tcx, signed), F32 => tcx.types.f32, @@ -627,29 +137,6 @@ impl<'a, 'tcx> Primitive { } } -/// Information about one scalar component of a Rust type. -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct Scalar { - pub value: Primitive, - - /// Inclusive wrap-around range of valid values, that is, if - /// min > max, it represents min..=u128::MAX followed by 0..=max. - // FIXME(eddyb) always use the shortest range, e.g. by finding - // the largest space between two consecutive valid values and - // taking everything else as the (shortest) valid range. - pub valid_range: RangeInclusive, -} - -impl Scalar { - pub fn is_bool(&self) -> bool { - if let Int(I8, _) = self.value { - self.valid_range == (0..=1) - } else { - false - } - } -} - /// The first half of a fat pointer. /// /// - For a trait object, this is the address of the box. @@ -662,183 +149,6 @@ pub const FAT_PTR_ADDR: usize = 0; /// - For a slice, this is the length. pub const FAT_PTR_EXTRA: usize = 1; -/// Describes how the fields of a type are located in memory. -#[derive(PartialEq, Eq, Hash, Debug)] -pub enum FieldPlacement { - /// All fields start at no offset. The `usize` is the field count. - Union(usize), - - /// Array/vector-like placement, with all fields of identical types. - Array { - stride: Size, - count: u64 - }, - - /// Struct-like placement, with precomputed offsets. - /// - /// Fields are guaranteed to not overlap, but note that gaps - /// before, between and after all the fields are NOT always - /// padding, and as such their contents may not be discarded. - /// For example, enum variants leave a gap at the start, - /// where the discriminant field in the enum layout goes. - Arbitrary { - /// Offsets for the first byte of each field, - /// ordered to match the source definition order. - /// This vector does not go in increasing order. - // FIXME(eddyb) use small vector optimization for the common case. - offsets: Vec, - - /// Maps source order field indices to memory order indices, - /// depending how fields were permuted. - // FIXME(camlorn) also consider small vector optimization here. - memory_index: Vec - } -} - -impl FieldPlacement { - pub fn count(&self) -> usize { - match *self { - FieldPlacement::Union(count) => count, - FieldPlacement::Array { count, .. } => { - let usize_count = count as usize; - assert_eq!(usize_count as u64, count); - usize_count - } - FieldPlacement::Arbitrary { ref offsets, .. } => offsets.len() - } - } - - pub fn offset(&self, i: usize) -> Size { - match *self { - FieldPlacement::Union(_) => Size::from_bytes(0), - FieldPlacement::Array { stride, count } => { - let i = i as u64; - assert!(i < count); - stride * i - } - FieldPlacement::Arbitrary { ref offsets, .. } => offsets[i] - } - } - - pub fn memory_index(&self, i: usize) -> usize { - match *self { - FieldPlacement::Union(_) | - FieldPlacement::Array { .. } => i, - FieldPlacement::Arbitrary { ref memory_index, .. } => { - let r = memory_index[i]; - assert_eq!(r as usize as u32, r); - r as usize - } - } - } - - /// Get source indices of the fields by increasing offsets. - #[inline] - pub fn index_by_increasing_offset<'a>(&'a self) -> impl iter::Iterator+'a { - let mut inverse_small = [0u8; 64]; - let mut inverse_big = vec![]; - let use_small = self.count() <= inverse_small.len(); - - // We have to write this logic twice in order to keep the array small. - if let FieldPlacement::Arbitrary { ref memory_index, .. } = *self { - if use_small { - for i in 0..self.count() { - inverse_small[memory_index[i] as usize] = i as u8; - } - } else { - inverse_big = vec![0; self.count()]; - for i in 0..self.count() { - inverse_big[memory_index[i] as usize] = i as u32; - } - } - } - - (0..self.count()).map(move |i| { - match *self { - FieldPlacement::Union(_) | - FieldPlacement::Array { .. } => i, - FieldPlacement::Arbitrary { .. } => { - if use_small { inverse_small[i] as usize } - else { inverse_big[i] as usize } - } - } - }) - } -} - -/// Describes how values of the type are passed by target ABIs, -/// in terms of categories of C types there are ABI rules for. -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub enum Abi { - Uninhabited, - Scalar(Scalar), - ScalarPair(Scalar, Scalar), - Vector { - element: Scalar, - count: u64 - }, - Aggregate { - /// If true, the size is exact, otherwise it's only a lower bound. - sized: bool, - } -} - -impl Abi { - /// Returns true if the layout corresponds to an unsized type. - pub fn is_unsized(&self) -> bool { - match *self { - Abi::Uninhabited | - Abi::Scalar(_) | - Abi::ScalarPair(..) | - Abi::Vector { .. } => false, - Abi::Aggregate { sized } => !sized - } - } - - /// Returns true if this is a single signed integer scalar - pub fn is_signed(&self) -> bool { - match *self { - Abi::Scalar(ref scal) => match scal.value { - Primitive::Int(_, signed) => signed, - _ => false, - }, - _ => false, - } - } -} - -#[derive(PartialEq, Eq, Hash, Debug)] -pub enum Variants { - /// Single enum variants, structs/tuples, unions, and all non-ADTs. - Single { - index: usize - }, - - /// General-case enums: for each case there is a struct, and they all have - /// all space reserved for the discriminant, and their first field starts - /// at a non-0 offset, after where the discriminant would go. - Tagged { - discr: Scalar, - variants: Vec, - }, - - /// Multiple cases distinguished by a niche (values invalid for a type): - /// the variant `dataful_variant` contains a niche at an arbitrary - /// offset (field 0 of the enum), which for a variant with discriminant - /// `d` is set to `(d - niche_variants.start).wrapping_add(niche_start)`. - /// - /// For example, `Option<(usize, &T)>` is represented such that - /// `None` has a null pointer for the second tuple field, and - /// `Some` is the identity function (with a non-null reference). - NicheFilling { - dataful_variant: usize, - niche_variants: RangeInclusive, - niche: Scalar, - niche_start: u128, - variants: Vec, - } -} - #[derive(Copy, Clone, Debug)] pub enum LayoutError<'tcx> { Unknown(Ty<'tcx>), @@ -858,40 +168,6 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { } } -#[derive(PartialEq, Eq, Hash, Debug)] -pub struct LayoutDetails { - pub variants: Variants, - pub fields: FieldPlacement, - pub abi: Abi, - pub align: Align, - pub size: Size -} - -impl LayoutDetails { - fn scalar(cx: C, scalar: Scalar) -> Self { - let size = scalar.value.size(cx); - let align = scalar.value.align(cx); - LayoutDetails { - variants: Variants::Single { index: 0 }, - fields: FieldPlacement::Union(0), - abi: Abi::Scalar(scalar), - size, - align, - } - } - - fn uninhabited(field_count: usize) -> Self { - let align = Align::from_bytes(1, 1).unwrap(); - LayoutDetails { - variants: Variants::Single { index: 0 }, - fields: FieldPlacement::Union(field_count), - abi: Abi::Uninhabited, - align, - size: Size::from_bytes(0) - } - } -} - fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> @@ -1525,9 +801,9 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { if let Some(i) = dataful_variant { let count = (niche_variants.end - niche_variants.start + 1) as u128; - for (field_index, field) in variants[i].iter().enumerate() { + for (field_index, &field) in variants[i].iter().enumerate() { let (offset, niche, niche_start) = - match field.find_niche(self, count)? { + match self.find_niche(field, count)? { Some(niche) => niche, None => continue }; @@ -2024,26 +1300,6 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> { } } -/// The details of the layout of a type, alongside the type itself. -/// Provides various type traversal APIs (e.g. recursing into fields). -/// -/// Note that the details are NOT guaranteed to always be identical -/// to those obtained from `layout_of(ty)`, as we need to produce -/// layouts for which Rust types do not exist, such as enum variants -/// or synthetic fields of enums (i.e. discriminants) and fat pointers. -#[derive(Copy, Clone, Debug)] -pub struct TyLayout<'tcx> { - pub ty: Ty<'tcx>, - details: &'tcx LayoutDetails -} - -impl<'tcx> Deref for TyLayout<'tcx> { - type Target = &'tcx LayoutDetails; - fn deref(&self) -> &&'tcx LayoutDetails { - &self.details - } -} - pub trait HasTyCtxt<'tcx>: HasDataLayout { fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>; } @@ -2095,13 +1351,10 @@ impl MaybeResult for Result { } } -pub trait LayoutOf { - type TyLayout; +pub type TyLayout<'tcx> = ::rustc_target::abi::TyLayout<'tcx, Ty<'tcx>>; - fn layout_of(self, ty: T) -> Self::TyLayout; -} - -impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { +impl<'a, 'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { + type Ty = Ty<'tcx>; type TyLayout = Result, LayoutError<'tcx>>; /// Computes the layout of a type. Note that this implicitly @@ -2127,7 +1380,8 @@ impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } } -impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>> { +impl<'a, 'tcx> LayoutOf for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>> { + type Ty = Ty<'tcx>; type TyLayout = Result, LayoutError<'tcx>>; /// Computes the layout of a type. Note that this implicitly @@ -2186,22 +1440,22 @@ impl<'a, 'tcx> ty::maps::TyCtxtAt<'a, 'tcx, 'tcx> { } } -impl<'a, 'tcx> TyLayout<'tcx> { - pub fn for_variant(&self, cx: C, variant_index: usize) -> Self - where C: LayoutOf> + HasTyCtxt<'tcx>, - C::TyLayout: MaybeResult> - { - let details = match self.variants { - Variants::Single { index } if index == variant_index => self.details, +impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx> + where C: LayoutOf> + HasTyCtxt<'tcx>, + C::TyLayout: MaybeResult> +{ + fn for_variant(this: TyLayout<'tcx>, cx: C, variant_index: usize) -> TyLayout<'tcx> { + let details = match this.variants { + Variants::Single { index } if index == variant_index => this.details, Variants::Single { index } => { // Deny calling for_variant more than once for non-Single enums. - cx.layout_of(self.ty).map_same(|layout| { + cx.layout_of(this.ty).map_same(|layout| { assert_eq!(layout.variants, Variants::Single { index }); layout }); - let fields = match self.ty.sty { + let fields = match this.ty.sty { ty::TyAdt(def, _) => def.variants[variant_index].fields.len(), _ => bug!() }; @@ -2219,17 +1473,14 @@ impl<'a, 'tcx> TyLayout<'tcx> { assert_eq!(details.variants, Variants::Single { index: variant_index }); TyLayout { - ty: self.ty, + ty: this.ty, details } } - pub fn field(&self, cx: C, i: usize) -> C::TyLayout - where C: LayoutOf> + HasTyCtxt<'tcx>, - C::TyLayout: MaybeResult> - { + fn field(this: TyLayout<'tcx>, cx: C, i: usize) -> C::TyLayout { let tcx = cx.tcx(); - cx.layout_of(match self.ty.sty { + cx.layout_of(match this.ty.sty { ty::TyBool | ty::TyChar | ty::TyInt(_) | @@ -2241,7 +1492,7 @@ impl<'a, 'tcx> TyLayout<'tcx> { ty::TyGeneratorWitness(..) | ty::TyForeign(..) | ty::TyDynamic(..) => { - bug!("TyLayout::field_type({:?}): not applicable", self) + bug!("TyLayout::field_type({:?}): not applicable", this) } // Potentially-fat pointers. @@ -2255,13 +1506,13 @@ impl<'a, 'tcx> TyLayout<'tcx> { // as the `Abi` or `FieldPlacement` is checked by users. if i == 0 { let nil = tcx.mk_nil(); - let ptr_ty = if self.ty.is_unsafe_ptr() { + let ptr_ty = if this.ty.is_unsafe_ptr() { tcx.mk_mut_ptr(nil) } else { tcx.mk_mut_ref(tcx.types.re_static, nil) }; return cx.layout_of(ptr_ty).map_same(|mut ptr_layout| { - ptr_layout.ty = self.ty; + ptr_layout.ty = this.ty; ptr_layout }); } @@ -2274,7 +1525,7 @@ impl<'a, 'tcx> TyLayout<'tcx> { // the correct number of vtables slots. tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil()) } - _ => bug!("TyLayout::field_type({:?}): not applicable", self) + _ => bug!("TyLayout::field_type({:?}): not applicable", this) } } @@ -2296,12 +1547,12 @@ impl<'a, 'tcx> TyLayout<'tcx> { // SIMD vector types. ty::TyAdt(def, ..) if def.repr.simd() => { - self.ty.simd_type(tcx) + this.ty.simd_type(tcx) } // ADTs. ty::TyAdt(def, substs) => { - match self.variants { + match this.variants { Variants::Single { index } => { def.variants[index].fields[i].ty(tcx, substs) } @@ -2321,45 +1572,25 @@ impl<'a, 'tcx> TyLayout<'tcx> { ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) | ty::TyInfer(_) | ty::TyError => { - bug!("TyLayout::field_type: unexpected type `{}`", self.ty) + bug!("TyLayout::field_type: unexpected type `{}`", this.ty) } }) } +} - /// Returns true if the layout corresponds to an unsized type. - pub fn is_unsized(&self) -> bool { - self.abi.is_unsized() - } - - /// Returns true if the type is a ZST and not unsized. - pub fn is_zst(&self) -> bool { - match self.abi { - Abi::Uninhabited => true, - Abi::Scalar(_) | - Abi::ScalarPair(..) | - Abi::Vector { .. } => false, - Abi::Aggregate { sized } => sized && self.size.bytes() == 0 - } - } - - pub fn size_and_align(&self) -> (Size, Align) { - (self.size, self.align) - } - +impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { /// Find the offset of a niche leaf field, starting from /// the given type and recursing through aggregates, which /// has at least `count` consecutive invalid values. /// The tuple is `(offset, scalar, niche_value)`. // FIXME(eddyb) traverse already optimized enums. - fn find_niche(&self, cx: C, count: u128) + fn find_niche(self, layout: TyLayout<'tcx>, count: u128) -> Result, LayoutError<'tcx>> - where C: LayoutOf, TyLayout = Result>> + - HasTyCtxt<'tcx> { let scalar_component = |scalar: &Scalar, offset| { let Scalar { value, valid_range: ref v } = *scalar; - let bits = value.size(cx).bits(); + let bits = value.size(self).bits(); assert!(bits <= 128); let max_value = !0u128 >> (128 - bits); @@ -2386,17 +1617,17 @@ impl<'a, 'tcx> TyLayout<'tcx> { // Locals variables which live across yields are stored // in the generator type as fields. These may be uninitialized // so we don't look for niches there. - if let ty::TyGenerator(..) = self.ty.sty { + if let ty::TyGenerator(..) = layout.ty.sty { return Ok(None); } - match self.abi { + match layout.abi { Abi::Scalar(ref scalar) => { return Ok(scalar_component(scalar, Size::from_bytes(0))); } Abi::ScalarPair(ref a, ref b) => { return Ok(scalar_component(a, Size::from_bytes(0)).or_else(|| { - scalar_component(b, a.value.size(cx).abi_align(b.value.align(cx))) + scalar_component(b, a.value.size(self).abi_align(b.value.align(self))) })); } Abi::Vector { ref element, .. } => { @@ -2406,22 +1637,22 @@ impl<'a, 'tcx> TyLayout<'tcx> { } // Perhaps one of the fields is non-zero, let's recurse and find out. - if let FieldPlacement::Union(_) = self.fields { + if let FieldPlacement::Union(_) = layout.fields { // Only Rust enums have safe-to-inspect fields // (a discriminant), other unions are unsafe. - if let Variants::Single { .. } = self.variants { + if let Variants::Single { .. } = layout.variants { return Ok(None); } } - if let FieldPlacement::Array { .. } = self.fields { - if self.fields.count() > 0 { - return self.field(cx, 0)?.find_niche(cx, count); + if let FieldPlacement::Array { .. } = layout.fields { + if layout.fields.count() > 0 { + return self.find_niche(layout.field(self, 0)?, count); } } - for i in 0..self.fields.count() { - let r = self.field(cx, i)?.find_niche(cx, count)?; + for i in 0..layout.fields.count() { + let r = self.find_niche(layout.field(self, i)?, count)?; if let Some((offset, scalar, niche_value)) = r { - let offset = self.fields.offset(i) + offset; + let offset = layout.fields.offset(i) + offset; return Ok(Some((offset, scalar, niche_value))); } } @@ -2549,14 +1780,22 @@ impl_stable_hash_for!(enum ::ty::layout::Primitive { Pointer }); -impl_stable_hash_for!(struct ::ty::layout::Align { - abi_pow2, - pref_pow2 -}); +impl<'gcx> HashStable> for Align { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'gcx>, + hasher: &mut StableHasher) { + self.abi().hash_stable(hcx, hasher); + self.pref().hash_stable(hcx, hasher); + } +} -impl_stable_hash_for!(struct ::ty::layout::Size { - raw -}); +impl<'gcx> HashStable> for Size { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'gcx>, + hasher: &mut StableHasher) { + self.bytes().hash_stable(hcx, hasher); + } +} impl<'a, 'gcx> HashStable> for LayoutError<'gcx> { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 92d23d4338f9d..f5cb3643de832 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -45,7 +45,7 @@ use util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet}; use util::common::{profq_msg, ErrorReported, ProfileQueriesMsg}; use rustc_data_structures::indexed_set::IdxSetBuf; -use rustc_back::PanicStrategy; +use rustc_target::spec::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::StableVec; diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 348cf03dd8783..03ed6e7ac90d1 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -22,7 +22,7 @@ use mir::interpret::{GlobalId, Value, PrimVal}; use util::common::ErrorReported; use std::rc::Rc; use std::iter; -use syntax::abi; +use rustc_target::spec::abi; use hir as ast; use rustc_data_structures::accumulate_vec::AccumulateVec; diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 199a46678c83c..9b20fce667318 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -44,7 +44,7 @@ CloneTypeFoldableAndLiftImpls! { ::hir::MatchSource, ::hir::Mutability, ::hir::Unsafety, - ::syntax::abi::Abi, + ::rustc_target::spec::abi::Abi, ::mir::Local, ::mir::Promoted, ::traits::Reveal, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 92e879a584b39..0dfae13cc753a 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -22,7 +22,7 @@ use util::captures::Captures; use std::iter; use std::cmp::Ordering; -use syntax::abi; +use rustc_target::spec::abi; use syntax::ast::{self, Name}; use syntax::symbol::{keywords, InternedString}; diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index b23e9124ddc91..a10ca13247216 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -22,7 +22,7 @@ use ty::fold::TypeVisitor; use ty::subst::UnpackedKind; use ty::maps::TyCtxtAt; use ty::TypeVariants::*; -use ty::layout::Integer; +use ty::layout::{Integer, IntegerExt}; use util::common::ErrorReported; use middle::lang_items; use mir::interpret::{Value, PrimVal}; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index efe83252d0fac..905776373bd37 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -28,7 +28,7 @@ use std::fmt; use std::usize; use rustc_data_structures::indexed_vec::Idx; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast::CRATE_NODE_ID; use syntax::symbol::{Symbol, InternedString}; use hir; diff --git a/src/librustc_allocator/Cargo.toml b/src/librustc_allocator/Cargo.toml index e3d1d8e32c4b7..765cb80f35710 100644 --- a/src/librustc_allocator/Cargo.toml +++ b/src/librustc_allocator/Cargo.toml @@ -11,5 +11,6 @@ test = false [dependencies] rustc = { path = "../librustc" } rustc_errors = { path = "../librustc_errors" } +rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 9338d000c1291..de8814d3d6a73 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -10,7 +10,7 @@ use rustc::middle::allocator::AllocatorKind; use rustc_errors; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast::{Attribute, Crate, LitKind, StrStyle}; use syntax::ast::{Arg, Constness, Generics, Mac, Mutability, Ty, Unsafety}; use syntax::ast::{self, Expr, Ident, Item, ItemKind, TyKind, VisibilityKind}; diff --git a/src/librustc_allocator/lib.rs b/src/librustc_allocator/lib.rs index 969086815ded4..6595564fb30b5 100644 --- a/src/librustc_allocator/lib.rs +++ b/src/librustc_allocator/lib.rs @@ -12,6 +12,7 @@ extern crate rustc; extern crate rustc_errors; +extern crate rustc_target; extern crate syntax; extern crate syntax_pos; diff --git a/src/librustc_back/README.md b/src/librustc_back/README.md deleted file mode 100644 index 3c01692c12b3c..0000000000000 --- a/src/librustc_back/README.md +++ /dev/null @@ -1,6 +0,0 @@ -`librustc_back` contains some very low-level details that are -specific to different LLVM targets and so forth. - -For more information about how trans works, see the [rustc guide]. - -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trans.html diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs deleted file mode 100644 index 027a9c4555530..0000000000000 --- a/src/librustc_back/lib.rs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Some stuff used by rustc that doesn't have many dependencies -//! -//! Originally extracted from rustc::back, which was nominally the -//! compiler 'backend', though LLVM is rustc's backend, so rustc_back -//! is really just odds-and-ends relating to code gen and linking. -//! This crate mostly exists to make rustc smaller, so we might put -//! more 'stuff' here in the future. It does not have a dependency on -//! rustc_llvm. -//! -//! FIXME: Split this into two crates: one that has deps on syntax, and -//! one that doesn't; the one that doesn't might get decent parallel -//! build speedups. - -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/")] - -#![feature(box_syntax)] -#![feature(const_fn)] -#![feature(fs_read_write)] - -extern crate syntax; -extern crate rand; -extern crate serialize; -#[macro_use] extern crate log; - -extern crate serialize as rustc_serialize; // used by deriving - -pub mod target; - -use std::str::FromStr; - -use serialize::json::{Json, ToJson}; - -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, - RustcEncodable, RustcDecodable)] -pub enum LinkerFlavor { - Em, - Gcc, - Ld, - Msvc, - Lld(LldFlavor), -} - -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, - RustcEncodable, RustcDecodable)] -pub enum LldFlavor { - Wasm, - Ld64, - Ld, - Link, -} - -impl ToJson for LinkerFlavor { - fn to_json(&self) -> Json { - self.desc().to_json() - } -} -macro_rules! flavor_mappings { - ($((($($flavor:tt)*), $string:expr),)*) => ( - impl LinkerFlavor { - pub const fn one_of() -> &'static str { - concat!("one of: ", $($string, " ",)+) - } - - pub fn from_str(s: &str) -> Option { - Some(match s { - $($string => $($flavor)*,)+ - _ => return None, - }) - } - - pub fn desc(&self) -> &str { - match *self { - $($($flavor)* => $string,)+ - } - } - } - ) -} - - -flavor_mappings! { - ((LinkerFlavor::Em), "em"), - ((LinkerFlavor::Gcc), "gcc"), - ((LinkerFlavor::Ld), "ld"), - ((LinkerFlavor::Msvc), "msvc"), - ((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"), - ((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"), - ((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"), - ((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"), -} - -#[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(), - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] -pub enum RelroLevel { - Full, - Partial, - Off, - None, -} - -impl RelroLevel { - pub fn desc(&self) -> &str { - match *self { - RelroLevel::Full => "full", - RelroLevel::Partial => "partial", - RelroLevel::Off => "off", - RelroLevel::None => "none", - } - } -} - -impl FromStr for RelroLevel { - type Err = (); - - fn from_str(s: &str) -> Result { - match s { - "full" => Ok(RelroLevel::Full), - "partial" => Ok(RelroLevel::Partial), - "off" => Ok(RelroLevel::Off), - "none" => Ok(RelroLevel::None), - _ => Err(()), - } - } -} - -impl ToJson for RelroLevel { - fn to_json(&self) -> Json { - match *self { - RelroLevel::Full => "full".to_json(), - RelroLevel::Partial => "partial".to_json(), - RelroLevel::Off => "off".to_json(), - RelroLevel::None => "None".to_json(), - } - } -} diff --git a/src/librustc_cratesio_shim/Cargo.toml b/src/librustc_cratesio_shim/Cargo.toml index 143f88e8f4b8e..342c7d1b67866 100644 --- a/src/librustc_cratesio_shim/Cargo.toml +++ b/src/librustc_cratesio_shim/Cargo.toml @@ -21,3 +21,4 @@ crate-type = ["dylib"] [dependencies] bitflags = "1.0" +log = "0.4" diff --git a/src/librustc_cratesio_shim/src/lib.rs b/src/librustc_cratesio_shim/src/lib.rs index 769b4f57206ec..85a5b331d8c45 100644 --- a/src/librustc_cratesio_shim/src/lib.rs +++ b/src/librustc_cratesio_shim/src/lib.rs @@ -12,3 +12,4 @@ #![allow(unused_extern_crates)] extern crate bitflags; +extern crate log; diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index e1f0a74fc683d..9178d0d00faa4 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["dylib"] [dependencies] ena = "0.9.1" log = "0.4" +rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } serialize = { path = "../libserialize" } cfg-if = "0.1.2" stable_deref_trait = "1.0.0" diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index ba1d73dc268df..1320fe75bc526 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -45,6 +45,10 @@ extern crate parking_lot; extern crate cfg_if; extern crate stable_deref_trait; +// See librustc_cratesio_shim/Cargo.toml for a comment explaining this. +#[allow(unused_extern_crates)] +extern crate rustc_cratesio_shim; + pub use rustc_serialize::hex::ToHex; pub mod array_vec; diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 3bff79ed3a6fc..5aae1bcad896f 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -15,7 +15,7 @@ log = "0.4" env_logger = { version = "0.5", default-features = false } rustc = { path = "../librustc" } rustc_allocator = { path = "../librustc_allocator" } -rustc_back = { path = "../librustc_back" } +rustc_target = { path = "../librustc_target" } rustc_borrowck = { path = "../librustc_borrowck" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index fb333ec38fb60..b203f387e4662 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -35,7 +35,7 @@ extern crate env_logger; extern crate libc; extern crate rustc; extern crate rustc_allocator; -extern crate rustc_back; +extern crate rustc_target; extern crate rustc_borrowck; extern crate rustc_data_structures; extern crate rustc_errors as errors; @@ -1021,7 +1021,7 @@ impl RustcDefaultCalls { for req in &sess.opts.prints { match *req { TargetList => { - let mut targets = rustc_back::target::get_targets().collect::>(); + let mut targets = rustc_target::spec::get_targets().collect::>(); targets.sort(); println!("{}", targets.join("\n")); }, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 83501f45ec037..47c49fbe9ef47 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -31,7 +31,7 @@ use rustc::session::config::{OutputFilenames, OutputTypes}; use rustc_data_structures::sync::{self, Lrc}; use syntax; use syntax::ast; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::codemap::{CodeMap, FilePathMapping, FileName}; use errors; use errors::emitter::Emitter; diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 5ff891202dbc5..f097095abe4e9 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -13,5 +13,6 @@ test = false log = "0.4" rustc = { path = "../librustc" } rustc_mir = { path = "../librustc_mir"} +rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 463ec4796e8b6..651a2e187f6b4 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -13,7 +13,7 @@ use rustc::ty; use lint::{LateContext, LintContext, LintArray}; use lint::{LintPass, LateLintPass}; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr; use syntax_pos::Span; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 76991e3e52d57..91ce6f3854a50 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1169,7 +1169,7 @@ impl LintPass for MutableTransmutes { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { fn check_expr(&mut self, cx: &LateContext, expr: &hir::Expr) { - use syntax::abi::Abi::RustIntrinsic; + use rustc_target::spec::abi::Abi::RustIntrinsic; let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \ consider instead using an UnsafeCell"; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 889c7d3e34ef9..65b340d65686d 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -37,6 +37,7 @@ extern crate rustc; #[macro_use] extern crate log; extern crate rustc_mir; +extern crate rustc_target; extern crate syntax_pos; use rustc::lint; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 445fe0cc40197..904a3e4c4274f 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -13,7 +13,7 @@ use rustc::hir::map as hir_map; use rustc::ty::subst::Substs; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; -use rustc::ty::layout::{self, LayoutOf}; +use rustc::ty::layout::{self, IntegerExt, LayoutOf}; use util::nodemap::FxHashSet; use lint::{LateContext, LintContext, LintArray}; use lint::{LintPass, LateLintPass}; @@ -22,7 +22,7 @@ use std::cmp; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use syntax::{ast, attr}; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax_pos::Span; use syntax::codemap; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index a2dcf7f3f83f2..338824d5efe4c 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -13,7 +13,7 @@ flate2 = "1.0" log = "0.4" proc_macro = { path = "../libproc_macro" } rustc = { path = "../librustc" } -rustc_back = { path = "../librustc_back" } +rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } serialize = { path = "../libserialize" } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 8a18a4b5290f8..d0237071a6058 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -21,8 +21,7 @@ use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::DepKind; use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; -use rustc_back::PanicStrategy; -use rustc_back::target::TargetTriple; +use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; use rustc::middle; use rustc::middle::cstore::{validate_crate_name, ExternCrate, ExternCrateSource}; diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 8765d9d8c2bed..64bbcf436cb9e 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -18,7 +18,7 @@ use rustc::hir::map::definitions::DefPathTable; use rustc::hir::svh::Svh; use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; use rustc::session::{Session, CrateDisambiguator}; -use rustc_back::PanicStrategy; +use rustc_target::spec::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc::util::nodemap::{FxHashMap, NodeMap}; diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 9ecb3fd6cddf6..a99e0a32e6645 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -38,7 +38,7 @@ extern crate proc_macro; #[macro_use] extern crate rustc; -extern crate rustc_back; +extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs index 6fafde0d09c16..b699885b0eb92 100644 --- a/src/librustc_metadata/link_args.rs +++ b/src/librustc_metadata/link_args.rs @@ -11,7 +11,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; use rustc::ty::TyCtxt; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec { let mut collector = Collector { diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index f553c55ae56fa..9b1b48efca585 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -236,7 +236,7 @@ use rustc::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; use syntax::symbol::Symbol; use syntax_pos::Span; -use rustc_back::target::{Target, TargetTriple}; +use rustc_target::spec::{Target, TargetTriple}; use std::cmp; use std::collections::HashSet; diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 4bb6d8fb87cf5..70b8c7b11fdb2 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -14,7 +14,7 @@ use rustc::middle::cstore::{self, NativeLibrary}; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::util::nodemap::FxHashSet; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::attr; use syntax::codemap::Span; use syntax::feature_gate::{self, GateIssue}; diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index ddeb797f1bef5..c9949389aceea 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -19,8 +19,7 @@ use rustc::middle::lang_items; use rustc::mir; use rustc::session::CrateDisambiguator; use rustc::ty::{self, Ty, ReprOptions}; -use rustc_back::PanicStrategy; -use rustc_back::target::TargetTriple; +use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_serialize as serialize; use syntax::{ast, attr}; diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 90a0f18aba367..a1b348774b163 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -15,7 +15,7 @@ graphviz = { path = "../libgraphviz" } log = "0.4" log_settings = "0.1.1" rustc = { path = "../librustc" } -rustc_back = { path = "../librustc_back" } +rustc_target = { path = "../librustc_target" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 28dc329e4fe7c..c130b4f550fd4 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -16,7 +16,7 @@ use hair::*; use rustc::ty; use rustc::mir::*; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Compile `expr`, storing the result into `destination`, which diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 9b0e4c64171ca..0d836f5cb9737 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -20,12 +20,12 @@ use rustc::mir::visit::{MutVisitor, TyContext}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Substs; use rustc::util::nodemap::NodeMap; -use rustc_back::PanicStrategy; +use rustc_target::spec::PanicStrategy; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use shim; use std::mem; use std::u32; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr::{self, UnwindAttr}; use syntax::symbol::keywords; diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index d8d5f5073abc1..e6aa2d3abb7e0 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -22,6 +22,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::hir::map::blocks::FnLikeNode; use rustc::middle::region; use rustc::infer::InferCtxt; +use rustc::ty::layout::IntegerExt; use rustc::ty::subst::Subst; use rustc::ty::{self, Ty, TyCtxt, layout}; use rustc::ty::subst::Substs; diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b98ab218de5cb..42f0e38af1f77 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -5,7 +5,7 @@ use rustc::hir::def::Def; use rustc::hir::map::definitions::DefPathData; use rustc::middle::const_val::{ConstVal, ErrKind}; use rustc::mir; -use rustc::ty::layout::{self, Size, Align, HasDataLayout, LayoutOf, TyLayout}; +use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout}; use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::maps::TyCtxtAt; @@ -162,7 +162,8 @@ impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> layout::HasTyCtxt<'tcx> } } -impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf> for &'a EvalContext<'a, 'mir, 'tcx, M> { +impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for &'a EvalContext<'a, 'mir, 'tcx, M> { + type Ty = Ty<'tcx>; type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>; fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { @@ -171,8 +172,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf> for &'a EvalCont } } -impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf> +impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for &'c &'b mut EvalContext<'a, 'mir, 'tcx, M> { + type Ty = Ty<'tcx>; type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>; #[inline] diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index 3360e5b72a7c7..aa80ee7af18fc 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -2,7 +2,7 @@ use rustc::mir; use rustc::ty::{self, Ty}; use rustc::ty::layout::LayoutOf; use syntax::codemap::Span; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use rustc::mir::interpret::{EvalResult, PrimVal, Value}; use super::{EvalContext, Place, Machine, ValTy}; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index a47b3cacc517e..399892522a353 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -49,7 +49,7 @@ extern crate rustc_errors; #[macro_use] extern crate syntax; extern crate syntax_pos; -extern crate rustc_back; +extern crate rustc_target; extern crate rustc_const_math; extern crate core; // for NonZero extern crate log_settings; diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 181751f177709..9e0c977a3f062 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -339,7 +339,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { } let abi = sig.abi(); - if abi != ::syntax::abi::Abi::Rust { + if abi != ::rustc_target::spec::abi::Abi::Rust { output.push_str("extern \""); output.push_str(abi.name()); output.push_str("\" "); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 6a0f42c6dbb66..af60a83a4a2e9 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -20,7 +20,7 @@ use rustc::mir::interpret::{Value, PrimVal}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast; use syntax_pos::Span; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index a3d96f0c0739d..47b2f430bc70e 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -72,7 +72,8 @@ struct ConstPropagator<'b, 'a, 'tcx:'a+'b> { param_env: ParamEnv<'tcx>, } -impl<'a, 'b, 'tcx> LayoutOf> for &'a ConstPropagator<'a, 'b, 'tcx> { +impl<'a, 'b, 'tcx> LayoutOf for &'a ConstPropagator<'a, 'b, 'tcx> { + type Ty = ty::Ty<'tcx>; type TyLayout = Result, LayoutError<'tcx>>; fn layout_of(self, ty: ty::Ty<'tcx>) -> Self::TyLayout { diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 2dd805ccf9b59..2b491385d661d 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -28,7 +28,7 @@ use transform::{MirPass, MirSource}; use super::simplify::{remove_dead_blocks, CfgSimplifier}; use syntax::{attr}; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; const DEFAULT_THRESHOLD: usize = 50; const HINT_THRESHOLD: usize = 100; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 591732fbba911..ff7551ed6f4f8 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -29,7 +29,7 @@ use rustc::mir::*; use rustc::mir::traversal::ReversePostorder; use rustc::mir::visit::{PlaceContext, Visitor}; use rustc::middle::lang_items; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::attr; use syntax::ast::LitKind; use syntax::feature_gate::UnstableFeatures; diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 45e7a0d3f4c5a..8f67b9e7c3d9d 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use syntax::abi::{Abi}; +use rustc_target::spec::abi::{Abi}; use syntax::ast; use syntax_pos::Span; diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index 005faa55b5884..976614c9542a8 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -12,6 +12,7 @@ crate-type = ["dylib"] log = "0.4" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_target = { path = "../librustc_target" } rustc_typeck = { path = "../librustc_typeck" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 6a747decbd368..401a280412a11 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -22,6 +22,7 @@ extern crate rustc; extern crate log; extern crate rustc_data_structures; extern crate rustc_serialize; +extern crate rustc_target; extern crate rustc_typeck; #[macro_use] extern crate syntax; diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index a9df898efb635..829ed320d753b 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -237,7 +237,7 @@ impl Sig for ast::Ty { if f.unsafety == ast::Unsafety::Unsafe { text.push_str("unsafe "); } - if f.abi != ::syntax::abi::Abi::Rust { + if f.abi != ::rustc_target::spec::abi::Abi::Rust { text.push_str("extern"); text.push_str(&f.abi.to_string()); text.push(' '); @@ -388,7 +388,7 @@ impl Sig for ast::Item { if unsafety == ast::Unsafety::Unsafe { text.push_str("unsafe "); } - if abi != ::syntax::abi::Abi::Rust { + if abi != ::rustc_target::spec::abi::Abi::Rust { text.push_str("extern"); text.push_str(&abi.to_string()); text.push(' '); @@ -931,7 +931,7 @@ fn make_method_signature( if m.unsafety == ast::Unsafety::Unsafe { text.push_str("unsafe "); } - if m.abi != ::syntax::abi::Abi::Rust { + if m.abi != ::rustc_target::spec::abi::Abi::Rust { text.push_str("extern"); text.push_str(&m.abi.to_string()); text.push(' '); diff --git a/src/librustc_back/Cargo.toml b/src/librustc_target/Cargo.toml similarity index 63% rename from src/librustc_back/Cargo.toml rename to src/librustc_target/Cargo.toml index 4c5b1417a2f67..bb686e914a048 100644 --- a/src/librustc_back/Cargo.toml +++ b/src/librustc_target/Cargo.toml @@ -1,18 +1,18 @@ [package] authors = ["The Rust Project Developers"] -name = "rustc_back" +name = "rustc_target" version = "0.0.0" [lib] -name = "rustc_back" +name = "rustc_target" path = "lib.rs" crate-type = ["dylib"] [dependencies] -syntax = { path = "../libsyntax" } -serialize = { path = "../libserialize" } +bitflags = "1.0" log = "0.4" -rand = "0.4" +rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } +serialize = { path = "../libserialize" } [features] jemalloc = [] diff --git a/src/librustc_target/README.md b/src/librustc_target/README.md new file mode 100644 index 0000000000000..f5b1acb192133 --- /dev/null +++ b/src/librustc_target/README.md @@ -0,0 +1,6 @@ +`librustc_target` contains some very low-level details that are +specific to different compilation targets and so forth. + +For more information about how rustc works, see the [rustc guide]. + +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ diff --git a/src/librustc_trans/cabi_aarch64.rs b/src/librustc_target/abi/call/aarch64.rs similarity index 73% rename from src/librustc_trans/cabi_aarch64.rs rename to src/librustc_target/abi/call/aarch64.rs index 72ae1449de04e..90b5b97b51ee2 100644 --- a/src/librustc_trans/cabi_aarch64.rs +++ b/src/librustc_target/abi/call/aarch64.rs @@ -8,11 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform}; -use context::CodegenCx; +use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; +use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; -fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) - -> Option { +fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>) + -> Option + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ arg.layout.homogeneous_aggregate(cx).and_then(|unit| { let size = arg.layout.size; @@ -38,7 +41,10 @@ fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgTyp }) } -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); return; @@ -69,7 +75,10 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) ret.make_indirect(); } -fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) { +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); return; @@ -100,7 +109,10 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) arg.make_indirect(); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !fty.ret.is_ignore() { classify_ret_ty(cx, &mut fty.ret); } diff --git a/src/librustc_trans/cabi_arm.rs b/src/librustc_target/abi/call/arm.rs similarity index 69% rename from src/librustc_trans/cabi_arm.rs rename to src/librustc_target/abi/call/arm.rs index b6cf16cb8d508..249aad2d937ea 100644 --- a/src/librustc_trans/cabi_arm.rs +++ b/src/librustc_target/abi/call/arm.rs @@ -8,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform}; -use context::CodegenCx; -use llvm::CallConv; +use abi::call::{Conv, FnType, ArgType, Reg, RegKind, Uniform}; +use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use spec::HasTargetSpec; -fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) - -> Option { +fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>) + -> Option + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ arg.layout.homogeneous_aggregate(cx).and_then(|unit| { let size = arg.layout.size; @@ -39,7 +42,10 @@ fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgTyp }) } -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, vfp: bool) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>, vfp: bool) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); return; @@ -71,7 +77,10 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, ret.make_indirect(); } -fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, vfp: bool) { +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>, vfp: bool) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); return; @@ -92,11 +101,14 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, }); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout + HasTargetSpec +{ // If this is a target with a hard-float ABI, and the function is not explicitly // `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates. - let vfp = cx.sess().target.target.llvm_target.ends_with("hf") - && fty.cconv != CallConv::ArmAapcsCallConv + let vfp = cx.target_spec().llvm_target.ends_with("hf") + && fty.conv != Conv::ArmAapcs && !fty.variadic; if !fty.ret.is_ignore() { diff --git a/src/librustc_trans/cabi_asmjs.rs b/src/librustc_target/abi/call/asmjs.rs similarity index 71% rename from src/librustc_trans/cabi_asmjs.rs rename to src/librustc_target/abi/call/asmjs.rs index b182f833dd699..81d6f7b134b3e 100644 --- a/src/librustc_trans/cabi_asmjs.rs +++ b/src/librustc_target/abi/call/asmjs.rs @@ -8,15 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{FnType, ArgType, LayoutExt, Uniform}; -use context::CodegenCx; +use abi::call::{FnType, ArgType, Uniform}; +use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; // Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128 // See the https://github.com/kripken/emscripten-fastcomp-clang repository. // The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions. -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if ret.layout.is_aggregate() { if let Some(unit) = ret.layout.homogeneous_aggregate(cx) { let size = ret.layout.size; @@ -33,13 +36,16 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType) { if arg.layout.is_aggregate() { arg.make_indirect_byval(); } } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !fty.ret.is_ignore() { classify_ret_ty(cx, &mut fty.ret); } diff --git a/src/librustc_trans/cabi_hexagon.rs b/src/librustc_target/abi/call/hexagon.rs similarity index 84% rename from src/librustc_trans/cabi_hexagon.rs rename to src/librustc_target/abi/call/hexagon.rs index 7e7e483fea0c0..d37d5584591c4 100644 --- a/src/librustc_trans/cabi_hexagon.rs +++ b/src/librustc_target/abi/call/hexagon.rs @@ -10,9 +10,9 @@ #![allow(non_upper_case_globals)] -use abi::{FnType, ArgType, LayoutExt}; +use abi::call::{FnType, ArgType}; -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 { ret.make_indirect(); } else { @@ -20,7 +20,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 { arg.make_indirect(); } else { @@ -28,7 +28,7 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_trans/cabi_mips.rs b/src/librustc_target/abi/call/mips.rs similarity index 67% rename from src/librustc_trans/cabi_mips.rs rename to src/librustc_target/abi/call/mips.rs index cd567f517fe8c..5001499ea5d3b 100644 --- a/src/librustc_trans/cabi_mips.rs +++ b/src/librustc_target/abi/call/mips.rs @@ -8,24 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{ArgType, FnType, LayoutExt, Reg, Uniform}; -use context::CodegenCx; +use abi::call::{ArgType, FnType, Reg, Uniform}; +use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; -use rustc::ty::layout::Size; - -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - ret: &mut ArgType<'tcx>, - offset: &mut Size) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType, offset: &mut Size) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); } else { ret.make_indirect(); - *offset += cx.tcx.data_layout.pointer_size; + *offset += cx.data_layout().pointer_size; } } -fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { - let dl = &cx.tcx.data_layout; +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType, offset: &mut Size) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ + let dl = cx.data_layout(); let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); @@ -44,7 +44,9 @@ fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { *offset = offset.abi_align(align) + size.abi_align(align); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ let mut offset = Size::from_bytes(0); if !fty.ret.is_ignore() { classify_ret_ty(cx, &mut fty.ret, &mut offset); diff --git a/src/librustc_trans/cabi_mips64.rs b/src/librustc_target/abi/call/mips64.rs similarity index 72% rename from src/librustc_trans/cabi_mips64.rs rename to src/librustc_target/abi/call/mips64.rs index 231fe4c6edb67..e5cbc6424a450 100644 --- a/src/librustc_trans/cabi_mips64.rs +++ b/src/librustc_target/abi/call/mips64.rs @@ -8,14 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{ArgAttribute, ArgType, CastTarget, FnType, LayoutExt, PassMode, Reg, RegKind, Uniform}; -use context::CodegenCx; -use rustc::ty::layout::{self, Size}; +use abi::call::{ArgAttribute, ArgType, CastTarget, FnType, PassMode, Reg, RegKind, Uniform}; +use abi::{self, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods}; -fn extend_integer_width_mips(arg: &mut ArgType, bits: u64) { +fn extend_integer_width_mips(arg: &mut ArgType, bits: u64) { // Always sign extend u32 values on 64-bit mips - if let layout::Abi::Scalar(ref scalar) = arg.layout.abi { - if let layout::Int(i, signed) = scalar.value { + if let abi::Abi::Scalar(ref scalar) = arg.layout.abi { + if let abi::Int(i, signed) = scalar.value { if !signed && i.size().bits() == 32 { if let PassMode::Direct(ref mut attrs) = arg.mode { attrs.set(ArgAttribute::SExt); @@ -28,18 +27,24 @@ fn extend_integer_width_mips(arg: &mut ArgType, bits: u64) { arg.extend_integer_width_to(bits); } -fn float_reg<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &ArgType<'tcx>, i: usize) -> Option { +fn float_reg<'a, Ty, C>(cx: C, ret: &ArgType<'a, Ty>, i: usize) -> Option + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ match ret.layout.field(cx, i).abi { - layout::Abi::Scalar(ref scalar) => match scalar.value { - layout::F32 => Some(Reg::f32()), - layout::F64 => Some(Reg::f64()), + abi::Abi::Scalar(ref scalar) => match scalar.value { + abi::F32 => Some(Reg::f32()), + abi::F64 => Some(Reg::f64()), _ => None }, _ => None } } -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !ret.layout.is_aggregate() { extend_integer_width_mips(ret, 64); return; @@ -52,7 +57,7 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) // use of float registers to structures (not unions) containing exactly one or two // float fields. - if let layout::FieldPlacement::Arbitrary { .. } = ret.layout.fields { + if let abi::FieldPlacement::Arbitrary { .. } = ret.layout.fields { if ret.layout.fields.count() == 1 { if let Some(reg) = float_reg(cx, ret, 0) { ret.cast_to(reg); @@ -78,27 +83,30 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) } } -fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) { +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !arg.layout.is_aggregate() { extend_integer_width_mips(arg, 64); return; } - let dl = &cx.tcx.data_layout; + let dl = cx.data_layout(); let size = arg.layout.size; let mut prefix = [None; 8]; let mut prefix_index = 0; match arg.layout.fields { - layout::FieldPlacement::Array { .. } => { + abi::FieldPlacement::Array { .. } => { // Arrays are passed indirectly arg.make_indirect(); return; } - layout::FieldPlacement::Union(_) => { + abi::FieldPlacement::Union(_) => { // Unions and are always treated as a series of 64-bit integer chunks }, - layout::FieldPlacement::Arbitrary { .. } => { + abi::FieldPlacement::Arbitrary { .. } => { // Structures are split up into a series of 64-bit integer chunks, but any aligned // doubles not part of another aggregate are passed as floats. let mut last_offset = Size::from_bytes(0); @@ -108,8 +116,8 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) let offset = arg.layout.fields.offset(i); // We only care about aligned doubles - if let layout::Abi::Scalar(ref scalar) = field.abi { - if let layout::F64 = scalar.value { + if let abi::Abi::Scalar(ref scalar) = field.abi { + if let abi::F64 = scalar.value { if offset.is_abi_aligned(dl.f64_align) { // Insert enough integers to cover [last_offset, offset) assert!(last_offset.is_abi_aligned(dl.f64_align)); @@ -143,7 +151,10 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) }); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !fty.ret.is_ignore() { classify_ret_ty(cx, &mut fty.ret); } diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs new file mode 100644 index 0000000000000..2d8996bb5ae27 --- /dev/null +++ b/src/librustc_target/abi/call/mod.rs @@ -0,0 +1,511 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use abi::{self, Abi, Align, FieldPlacement, Size}; +use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use spec::HasTargetSpec; + +mod aarch64; +mod arm; +mod asmjs; +mod hexagon; +mod mips; +mod mips64; +mod msp430; +mod nvptx; +mod nvptx64; +mod powerpc; +mod powerpc64; +mod s390x; +mod sparc; +mod sparc64; +mod x86; +mod x86_64; +mod x86_win64; +mod wasm32; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum PassMode { + /// Ignore the argument (useful for empty struct). + Ignore, + /// Pass the argument directly. + Direct(ArgAttributes), + /// Pass a pair's elements directly in two arguments. + Pair(ArgAttributes, ArgAttributes), + /// Pass the argument after casting it, to either + /// a single uniform or a pair of registers. + Cast(CastTarget), + /// Pass the argument indirectly via a hidden pointer. + Indirect(ArgAttributes), +} + +// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest +// of this module +pub use self::attr_impl::ArgAttribute; + +#[allow(non_upper_case_globals)] +#[allow(unused)] +mod attr_impl { + // The subset of llvm::Attribute needed for arguments, packed into a bitfield. + bitflags! { + #[derive(Default)] + pub struct ArgAttribute: u16 { + const ByVal = 1 << 0; + const NoAlias = 1 << 1; + const NoCapture = 1 << 2; + const NonNull = 1 << 3; + const ReadOnly = 1 << 4; + const SExt = 1 << 5; + const StructRet = 1 << 6; + const ZExt = 1 << 7; + const InReg = 1 << 8; + } + } +} + +/// A compact representation of LLVM attributes (at least those relevant for this module) +/// that can be manipulated without interacting with LLVM's Attribute machinery. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub struct ArgAttributes { + pub regular: ArgAttribute, + pub pointee_size: Size, + pub pointee_align: Option +} + +impl ArgAttributes { + pub fn new() -> Self { + ArgAttributes { + regular: ArgAttribute::default(), + pointee_size: Size::from_bytes(0), + pointee_align: None, + } + } + + pub fn set(&mut self, attr: ArgAttribute) -> &mut Self { + self.regular = self.regular | attr; + self + } + + pub fn contains(&self, attr: ArgAttribute) -> bool { + self.regular.contains(attr) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum RegKind { + Integer, + Float, + Vector +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub struct Reg { + pub kind: RegKind, + pub size: Size, +} + +macro_rules! reg_ctor { + ($name:ident, $kind:ident, $bits:expr) => { + pub fn $name() -> Reg { + Reg { + kind: RegKind::$kind, + size: Size::from_bits($bits) + } + } + } +} + +impl Reg { + reg_ctor!(i8, Integer, 8); + reg_ctor!(i16, Integer, 16); + reg_ctor!(i32, Integer, 32); + reg_ctor!(i64, Integer, 64); + + reg_ctor!(f32, Float, 32); + reg_ctor!(f64, Float, 64); +} + +impl Reg { + pub fn align(&self, cx: C) -> Align { + let dl = cx.data_layout(); + match self.kind { + RegKind::Integer => { + match self.size.bits() { + 1 => dl.i1_align, + 2...8 => dl.i8_align, + 9...16 => dl.i16_align, + 17...32 => dl.i32_align, + 33...64 => dl.i64_align, + 65...128 => dl.i128_align, + _ => panic!("unsupported integer: {:?}", self) + } + } + RegKind::Float => { + match self.size.bits() { + 32 => dl.f32_align, + 64 => dl.f64_align, + _ => panic!("unsupported float: {:?}", self) + } + } + RegKind::Vector => dl.vector_align(self.size) + } + } +} + +/// An argument passed entirely registers with the +/// same kind (e.g. HFA / HVA on PPC64 and AArch64). +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct Uniform { + pub unit: Reg, + + /// The total size of the argument, which can be: + /// * equal to `unit.size` (one scalar/vector) + /// * a multiple of `unit.size` (an array of scalar/vectors) + /// * if `unit.kind` is `Integer`, the last element + /// can be shorter, i.e. `{ i64, i64, i32 }` for + /// 64-bit integers with a total size of 20 bytes + pub total: Size, +} + +impl From for Uniform { + fn from(unit: Reg) -> Uniform { + Uniform { + unit, + total: unit.size + } + } +} + +impl Uniform { + pub fn align(&self, cx: C) -> Align { + self.unit.align(cx) + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct CastTarget { + pub prefix: [Option; 8], + pub prefix_chunk: Size, + pub rest: Uniform, +} + +impl From for CastTarget { + fn from(unit: Reg) -> CastTarget { + CastTarget::from(Uniform::from(unit)) + } +} + +impl From for CastTarget { + fn from(uniform: Uniform) -> CastTarget { + CastTarget { + prefix: [None; 8], + prefix_chunk: Size::from_bytes(0), + rest: uniform + } + } +} + +impl CastTarget { + pub fn pair(a: Reg, b: Reg) -> CastTarget { + CastTarget { + prefix: [Some(a.kind), None, None, None, None, None, None, None], + prefix_chunk: a.size, + rest: Uniform::from(b) + } + } + + pub fn size(&self, cx: C) -> Size { + (self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64) + .abi_align(self.rest.align(cx)) + self.rest.total + } + + pub fn align(&self, cx: C) -> Align { + self.prefix.iter() + .filter_map(|x| x.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.align(cx))) + .fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)), + |acc, align| acc.max(align)) + } +} + +impl<'a, Ty> TyLayout<'a, Ty> { + fn is_aggregate(&self) -> bool { + match self.abi { + Abi::Uninhabited | + Abi::Scalar(_) | + Abi::Vector { .. } => false, + Abi::ScalarPair(..) | + Abi::Aggregate { .. } => true + } + } + + fn homogeneous_aggregate(&self, cx: C) -> Option + where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf + Copy + { + match self.abi { + Abi::Uninhabited => None, + + // The primitive for this algorithm. + Abi::Scalar(ref scalar) => { + let kind = match scalar.value { + abi::Int(..) | + abi::Pointer => RegKind::Integer, + abi::F32 | + abi::F64 => RegKind::Float + }; + Some(Reg { + kind, + size: self.size + }) + } + + Abi::Vector { .. } => { + Some(Reg { + kind: RegKind::Vector, + size: self.size + }) + } + + Abi::ScalarPair(..) | + Abi::Aggregate { .. } => { + let mut total = Size::from_bytes(0); + let mut result = None; + + let is_union = match self.fields { + FieldPlacement::Array { count, .. } => { + if count > 0 { + return self.field(cx, 0).homogeneous_aggregate(cx); + } else { + return None; + } + } + FieldPlacement::Union(_) => true, + FieldPlacement::Arbitrary { .. } => false + }; + + for i in 0..self.fields.count() { + if !is_union && total != self.fields.offset(i) { + return None; + } + + let field = self.field(cx, i); + match (result, field.homogeneous_aggregate(cx)) { + // The field itself must be a homogeneous aggregate. + (_, None) => return None, + // If this is the first field, record the unit. + (None, Some(unit)) => { + result = Some(unit); + } + // For all following fields, the unit must be the same. + (Some(prev_unit), Some(unit)) => { + if prev_unit != unit { + return None; + } + } + } + + // Keep track of the offset (without padding). + let size = field.size; + if is_union { + total = total.max(size); + } else { + total += size; + } + } + + // There needs to be no padding. + if total != self.size { + None + } else { + result + } + } + } + } +} + +/// Information about how to pass an argument to, +/// or return a value from, a function, under some ABI. +#[derive(Debug)] +pub struct ArgType<'a, Ty> { + pub layout: TyLayout<'a, Ty>, + + /// Dummy argument, which is emitted before the real argument. + pub pad: Option, + + pub mode: PassMode, +} + +impl<'a, Ty> ArgType<'a, Ty> { + pub fn new(layout: TyLayout<'a, Ty>) -> Self { + ArgType { + layout, + pad: None, + mode: PassMode::Direct(ArgAttributes::new()), + } + } + + pub fn make_indirect(&mut self) { + assert_eq!(self.mode, PassMode::Direct(ArgAttributes::new())); + + // Start with fresh attributes for the pointer. + let mut attrs = ArgAttributes::new(); + + // For non-immediate arguments the callee gets its own copy of + // the value on the stack, so there are no aliases. It's also + // program-invisible so can't possibly capture + attrs.set(ArgAttribute::NoAlias) + .set(ArgAttribute::NoCapture) + .set(ArgAttribute::NonNull); + attrs.pointee_size = self.layout.size; + // FIXME(eddyb) We should be doing this, but at least on + // i686-pc-windows-msvc, it results in wrong stack offsets. + // attrs.pointee_align = Some(self.layout.align); + + self.mode = PassMode::Indirect(attrs); + } + + pub fn make_indirect_byval(&mut self) { + self.make_indirect(); + match self.mode { + PassMode::Indirect(ref mut attrs) => { + attrs.set(ArgAttribute::ByVal); + } + _ => unreachable!() + } + } + + pub fn extend_integer_width_to(&mut self, bits: u64) { + // Only integers have signedness + if let Abi::Scalar(ref scalar) = self.layout.abi { + if let abi::Int(i, signed) = scalar.value { + if i.size().bits() < bits { + if let PassMode::Direct(ref mut attrs) = self.mode { + attrs.set(if signed { + ArgAttribute::SExt + } else { + ArgAttribute::ZExt + }); + } + } + } + } + } + + pub fn cast_to>(&mut self, target: T) { + assert_eq!(self.mode, PassMode::Direct(ArgAttributes::new())); + self.mode = PassMode::Cast(target.into()); + } + + pub fn pad_with(&mut self, reg: Reg) { + self.pad = Some(reg); + } + + pub fn is_indirect(&self) -> bool { + match self.mode { + PassMode::Indirect(_) => true, + _ => false + } + } + + pub fn is_ignore(&self) -> bool { + self.mode == PassMode::Ignore + } +} + +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum Conv { + C, + + ArmAapcs, + + Msp430Intr, + + PtxKernel, + + X86Fastcall, + X86Intr, + X86Stdcall, + X86ThisCall, + X86VectorCall, + + X86_64SysV, + X86_64Win64, +} + +/// Metadata describing how the arguments to a native function +/// should be passed in order to respect the native ABI. +/// +/// I will do my best to describe this structure, but these +/// comments are reverse-engineered and may be inaccurate. -NDM +#[derive(Debug)] +pub struct FnType<'a, Ty> { + /// The LLVM types of each argument. + pub args: Vec>, + + /// LLVM return type. + pub ret: ArgType<'a, Ty>, + + pub variadic: bool, + + pub conv: Conv, +} + +impl<'a, Ty> FnType<'a, Ty> { + pub fn adjust_for_cabi(&mut self, cx: C, abi: ::spec::abi::Abi) -> Result<(), String> + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout + HasTargetSpec + { + match &cx.target_spec().arch[..] { + "x86" => { + let flavor = if abi == ::spec::abi::Abi::Fastcall { + x86::Flavor::Fastcall + } else { + x86::Flavor::General + }; + x86::compute_abi_info(cx, self, flavor); + }, + "x86_64" => if abi == ::spec::abi::Abi::SysV64 { + x86_64::compute_abi_info(cx, self); + } else if abi == ::spec::abi::Abi::Win64 || cx.target_spec().options.is_like_windows { + x86_win64::compute_abi_info(self); + } else { + x86_64::compute_abi_info(cx, self); + }, + "aarch64" => aarch64::compute_abi_info(cx, self), + "arm" => arm::compute_abi_info(cx, self), + "mips" => mips::compute_abi_info(cx, self), + "mips64" => mips64::compute_abi_info(cx, self), + "powerpc" => powerpc::compute_abi_info(cx, self), + "powerpc64" => powerpc64::compute_abi_info(cx, self), + "s390x" => s390x::compute_abi_info(cx, self), + "asmjs" => asmjs::compute_abi_info(cx, self), + "wasm32" => { + if cx.target_spec().llvm_target.contains("emscripten") { + asmjs::compute_abi_info(cx, self) + } else { + wasm32::compute_abi_info(self) + } + } + "msp430" => msp430::compute_abi_info(self), + "sparc" => sparc::compute_abi_info(cx, self), + "sparc64" => sparc64::compute_abi_info(cx, self), + "nvptx" => nvptx::compute_abi_info(self), + "nvptx64" => nvptx64::compute_abi_info(self), + "hexagon" => hexagon::compute_abi_info(self), + a => return Err(format!("unrecognized arch \"{}\" in target specification", a)) + } + + if let PassMode::Indirect(ref mut attrs) = self.ret.mode { + attrs.set(ArgAttribute::StructRet); + } + + Ok(()) + } +} diff --git a/src/librustc_trans/cabi_msp430.rs b/src/librustc_target/abi/call/msp430.rs similarity index 89% rename from src/librustc_trans/cabi_msp430.rs rename to src/librustc_target/abi/call/msp430.rs index d270886a19cd1..e57ca03da6007 100644 --- a/src/librustc_trans/cabi_msp430.rs +++ b/src/librustc_target/abi/call/msp430.rs @@ -11,7 +11,7 @@ // Reference: MSP430 Embedded Application Binary Interface // http://www.ti.com/lit/an/slaa534/slaa534.pdf -use abi::{ArgType, FnType, LayoutExt}; +use abi::call::{ArgType, FnType}; // 3.5 Structures or Unions Passed and Returned by Reference // @@ -19,7 +19,7 @@ use abi::{ArgType, FnType, LayoutExt}; // returned by reference. To pass a structure or union by reference, the caller // places its address in the appropriate location: either in a register or on // the stack, according to its position in the argument list. (..)" -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 32 { ret.make_indirect(); } else { @@ -27,7 +27,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 32 { arg.make_indirect(); } else { @@ -35,7 +35,7 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_trans/cabi_nvptx.rs b/src/librustc_target/abi/call/nvptx.rs similarity index 85% rename from src/librustc_trans/cabi_nvptx.rs rename to src/librustc_target/abi/call/nvptx.rs index 69cfc690a9f9d..f23f7ddf2abcc 100644 --- a/src/librustc_trans/cabi_nvptx.rs +++ b/src/librustc_target/abi/call/nvptx.rs @@ -11,9 +11,9 @@ // Reference: PTX Writer's Guide to Interoperability // http://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability -use abi::{ArgType, FnType, LayoutExt}; +use abi::call::{ArgType, FnType}; -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 32 { ret.make_indirect(); } else { @@ -21,7 +21,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 32 { arg.make_indirect(); } else { @@ -29,7 +29,7 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_trans/cabi_nvptx64.rs b/src/librustc_target/abi/call/nvptx64.rs similarity index 85% rename from src/librustc_trans/cabi_nvptx64.rs rename to src/librustc_target/abi/call/nvptx64.rs index 4d76c15603800..4399a2fec6caf 100644 --- a/src/librustc_trans/cabi_nvptx64.rs +++ b/src/librustc_target/abi/call/nvptx64.rs @@ -11,9 +11,9 @@ // Reference: PTX Writer's Guide to Interoperability // http://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability -use abi::{ArgType, FnType, LayoutExt}; +use abi::call::{ArgType, FnType}; -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 { ret.make_indirect(); } else { @@ -21,7 +21,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 { arg.make_indirect(); } else { @@ -29,7 +29,7 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_trans/cabi_powerpc.rs b/src/librustc_target/abi/call/powerpc.rs similarity index 67% rename from src/librustc_trans/cabi_powerpc.rs rename to src/librustc_target/abi/call/powerpc.rs index 1ea6e9b26952d..8c3c2422d7f41 100644 --- a/src/librustc_trans/cabi_powerpc.rs +++ b/src/librustc_target/abi/call/powerpc.rs @@ -8,24 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{ArgType, FnType, LayoutExt, Reg, Uniform}; -use context::CodegenCx; +use abi::call::{ArgType, FnType, Reg, Uniform}; +use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; -use rustc::ty::layout::Size; - -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - ret: &mut ArgType<'tcx>, - offset: &mut Size) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType, offset: &mut Size) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); } else { ret.make_indirect(); - *offset += cx.tcx.data_layout.pointer_size; + *offset += cx.data_layout().pointer_size; } } -fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { - let dl = &cx.tcx.data_layout; +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType, offset: &mut Size) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ + let dl = cx.data_layout(); let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); @@ -44,7 +44,9 @@ fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { *offset = offset.abi_align(align) + size.abi_align(align); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ let mut offset = Size::from_bytes(0); if !fty.ret.is_ignore() { classify_ret_ty(cx, &mut fty.ret, &mut offset); diff --git a/src/librustc_trans/cabi_powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs similarity index 74% rename from src/librustc_trans/cabi_powerpc64.rs rename to src/librustc_target/abi/call/powerpc64.rs index c614cf3a5a9ea..0c5ec77a3982d 100644 --- a/src/librustc_trans/cabi_powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -12,9 +12,8 @@ // Alignment of 128 bit types is not currently handled, this will // need to be fixed when PowerPC vector support is added. -use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform}; -use context::CodegenCx; -use rustc::ty::layout; +use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; +use abi::{Align, Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; #[derive(Debug, Clone, Copy, PartialEq)] enum ABI { @@ -23,10 +22,11 @@ enum ABI { } use self::ABI::*; -fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - arg: &mut ArgType<'tcx>, - abi: ABI) - -> Option { +fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>, abi: ABI) + -> Option + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ arg.layout.homogeneous_aggregate(cx).and_then(|unit| { // ELFv1 only passes one-member aggregates transparently. // ELFv2 passes up to eight uniquely addressable members. @@ -52,7 +52,10 @@ fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, }) } -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, abi: ABI) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>, abi: ABI) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !ret.layout.is_aggregate() { ret.extend_integer_width_to(64); return; @@ -92,7 +95,10 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, ret.make_indirect(); } -fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, abi: ABI) { +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>, abi: ABI) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); return; @@ -112,7 +118,7 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, if size.bits() <= 64 { (Reg { kind: RegKind::Integer, size }, size) } else { - let align = layout::Align::from_bits(64, 64).unwrap(); + let align = Align::from_bits(64, 64).unwrap(); (Reg::i64(), size.abi_align(align)) } }, @@ -128,11 +134,13 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, }); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { - let abi = match cx.sess().target.target.target_endian.as_str() { - "big" => ELFv1, - "little" => ELFv2, - _ => unimplemented!(), +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ + let abi = match cx.data_layout().endian { + Endian::Big => ELFv1, + Endian::Little => ELFv2, }; if !fty.ret.is_ignore() { diff --git a/src/librustc_trans/cabi_s390x.rs b/src/librustc_target/abi/call/s390x.rs similarity index 67% rename from src/librustc_trans/cabi_s390x.rs rename to src/librustc_target/abi/call/s390x.rs index 5e817686defe2..3002a3c46c8a8 100644 --- a/src/librustc_trans/cabi_s390x.rs +++ b/src/librustc_target/abi/call/s390x.rs @@ -11,12 +11,12 @@ // FIXME: The assumes we're using the non-vector ABI, i.e. compiling // for a pre-z13 machine or using -mno-vx. -use abi::{FnType, ArgType, LayoutExt, Reg}; -use context::CodegenCx; +use abi::call::{FnType, ArgType, Reg}; +use abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; -use rustc::ty::layout::{self, TyLayout}; - -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty<'a, Ty, C>(ret: &mut ArgType) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 { ret.extend_integer_width_to(64); } else { @@ -24,16 +24,18 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn is_single_fp_element<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - layout: TyLayout<'tcx>) -> bool { +fn is_single_fp_element<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>) -> bool + where Ty: TyLayoutMethods<'a, C>, + C: LayoutOf> + HasDataLayout +{ match layout.abi { - layout::Abi::Scalar(ref scalar) => { + abi::Abi::Scalar(ref scalar) => { match scalar.value { - layout::F32 | layout::F64 => true, + abi::F32 | abi::F64 => true, _ => false } } - layout::Abi::Aggregate { .. } => { + abi::Abi::Aggregate { .. } => { if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 { is_single_fp_element(cx, layout.field(cx, 0)) } else { @@ -44,7 +46,10 @@ fn is_single_fp_element<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } } -fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) { +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 { arg.extend_integer_width_to(64); return; @@ -67,7 +72,10 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) } } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_trans/cabi_sparc.rs b/src/librustc_target/abi/call/sparc.rs similarity index 67% rename from src/librustc_trans/cabi_sparc.rs rename to src/librustc_target/abi/call/sparc.rs index cd567f517fe8c..5001499ea5d3b 100644 --- a/src/librustc_trans/cabi_sparc.rs +++ b/src/librustc_target/abi/call/sparc.rs @@ -8,24 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{ArgType, FnType, LayoutExt, Reg, Uniform}; -use context::CodegenCx; +use abi::call::{ArgType, FnType, Reg, Uniform}; +use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; -use rustc::ty::layout::Size; - -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - ret: &mut ArgType<'tcx>, - offset: &mut Size) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType, offset: &mut Size) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); } else { ret.make_indirect(); - *offset += cx.tcx.data_layout.pointer_size; + *offset += cx.data_layout().pointer_size; } } -fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { - let dl = &cx.tcx.data_layout; +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType, offset: &mut Size) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ + let dl = cx.data_layout(); let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); @@ -44,7 +44,9 @@ fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { *offset = offset.abi_align(align) + size.abi_align(align); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType) + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout +{ let mut offset = Size::from_bytes(0); if !fty.ret.is_ignore() { classify_ret_ty(cx, &mut fty.ret, &mut offset); diff --git a/src/librustc_trans/cabi_sparc64.rs b/src/librustc_target/abi/call/sparc64.rs similarity index 72% rename from src/librustc_trans/cabi_sparc64.rs rename to src/librustc_target/abi/call/sparc64.rs index b3fc6a6806118..987f56e6f9851 100644 --- a/src/librustc_trans/cabi_sparc64.rs +++ b/src/librustc_target/abi/call/sparc64.rs @@ -10,11 +10,14 @@ // FIXME: This needs an audit for correctness and completeness. -use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform}; -use context::CodegenCx; +use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; +use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; -fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) - -> Option { +fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>) + -> Option + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ arg.layout.homogeneous_aggregate(cx).and_then(|unit| { // Ensure we have at most eight uniquely addressable members. if arg.layout.size > unit.size.checked_mul(8, cx).unwrap() { @@ -38,7 +41,10 @@ fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgTyp }) } -fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { +fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !ret.layout.is_aggregate() { ret.extend_integer_width_to(64); return; @@ -72,7 +78,10 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) ret.make_indirect(); } -fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) { +fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); return; @@ -95,7 +104,10 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) }); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ if !fty.ret.is_ignore() { classify_ret_ty(cx, &mut fty.ret); } diff --git a/src/librustc_trans/cabi_wasm32.rs b/src/librustc_target/abi/call/wasm32.rs similarity index 69% rename from src/librustc_trans/cabi_wasm32.rs rename to src/librustc_target/abi/call/wasm32.rs index 5530a03d65dda..7109eea535d4a 100644 --- a/src/librustc_trans/cabi_wasm32.rs +++ b/src/librustc_target/abi/call/wasm32.rs @@ -8,20 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{FnType, ArgType}; -use context::CodegenCx; +use abi::call::{FnType, ArgType}; -fn classify_ret_ty<'a, 'tcx>(_cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { +fn classify_ret_ty(ret: &mut ArgType) { ret.extend_integer_width_to(32); } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType) { arg.extend_integer_width_to(32); } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info(fty: &mut FnType) { if !fty.ret.is_ignore() { - classify_ret_ty(cx, &mut fty.ret); + classify_ret_ty(&mut fty.ret); } for arg in &mut fty.args { diff --git a/src/librustc_trans/cabi_x86.rs b/src/librustc_target/abi/call/x86.rs similarity index 83% rename from src/librustc_trans/cabi_x86.rs rename to src/librustc_target/abi/call/x86.rs index b14558448067c..e803b96b21cfa 100644 --- a/src/librustc_trans/cabi_x86.rs +++ b/src/librustc_target/abi/call/x86.rs @@ -8,10 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{ArgAttribute, FnType, LayoutExt, PassMode, Reg, RegKind}; -use common::CodegenCx; - -use rustc::ty::layout::{self, TyLayout}; +use abi::call::{ArgAttribute, FnType, PassMode, Reg, RegKind}; +use abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use spec::HasTargetSpec; #[derive(PartialEq)] pub enum Flavor { @@ -19,16 +18,18 @@ pub enum Flavor { Fastcall } -fn is_single_fp_element<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - layout: TyLayout<'tcx>) -> bool { +fn is_single_fp_element<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>) -> bool + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ match layout.abi { - layout::Abi::Scalar(ref scalar) => { + abi::Abi::Scalar(ref scalar) => { match scalar.value { - layout::F32 | layout::F64 => true, + abi::F32 | abi::F64 => true, _ => false } } - layout::Abi::Aggregate { .. } => { + abi::Abi::Aggregate { .. } => { if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 { is_single_fp_element(cx, layout.field(cx, 0)) } else { @@ -39,9 +40,10 @@ fn is_single_fp_element<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - fty: &mut FnType<'tcx>, - flavor: Flavor) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>, flavor: Flavor) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout + HasTargetSpec +{ if !fty.ret.is_ignore() { if fty.ret.layout.is_aggregate() { // Returning a structure. Most often, this will use @@ -51,7 +53,7 @@ pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // Some links: // http://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp - let t = &cx.sess().target.target; + let t = cx.target_spec(); if t.options.abi_return_struct_as_int { // According to Clang, everyone but MSVC returns single-element // float aggregates directly in a floating-point register. @@ -106,7 +108,7 @@ pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, PassMode::Direct(ref mut attrs) => attrs, PassMode::Pair(..) | PassMode::Cast(_) => { - bug!("x86 shouldn't be passing arguments by {:?}", arg.mode) + unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode) } }; diff --git a/src/librustc_trans/cabi_x86_64.rs b/src/librustc_target/abi/call/x86_64.rs similarity index 81% rename from src/librustc_trans/cabi_x86_64.rs rename to src/librustc_target/abi/call/x86_64.rs index 7eadaa7f493a3..0ba1ee736e769 100644 --- a/src/librustc_trans/cabi_x86_64.rs +++ b/src/librustc_target/abi/call/x86_64.rs @@ -11,10 +11,8 @@ // The classification code for the x86_64 ABI is taken from the clay language // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp -use abi::{ArgType, CastTarget, FnType, LayoutExt, Reg, RegKind}; -use context::CodegenCx; - -use rustc::ty::layout::{self, TyLayout, Size}; +use abi::call::{ArgType, CastTarget, FnType, Reg, RegKind}; +use abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods}; /// Classification of "eightbyte" components. // NB: the order of the variants is from general to specific, @@ -33,13 +31,16 @@ struct Memory; const LARGEST_VECTOR_SIZE: usize = 512; const MAX_EIGHTBYTES: usize = LARGEST_VECTOR_SIZE / 64; -fn classify_arg<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &ArgType<'tcx>) - -> Result<[Option; MAX_EIGHTBYTES], Memory> { - fn classify<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - layout: TyLayout<'tcx>, - cls: &mut [Option], - off: Size) - -> Result<(), Memory> { +fn classify_arg<'a, Ty, C>(cx: C, arg: &ArgType<'a, Ty>) + -> Result<[Option; MAX_EIGHTBYTES], Memory> + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ + fn classify<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>, + cls: &mut [Option], off: Size) -> Result<(), Memory> + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout + { if !off.is_abi_aligned(layout.align) { if !layout.is_zst() { return Err(Memory); @@ -48,31 +49,31 @@ fn classify_arg<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &ArgType<'tcx>) } let mut c = match layout.abi { - layout::Abi::Uninhabited => return Ok(()), + Abi::Uninhabited => return Ok(()), - layout::Abi::Scalar(ref scalar) => { + Abi::Scalar(ref scalar) => { match scalar.value { - layout::Int(..) | - layout::Pointer => Class::Int, - layout::F32 | - layout::F64 => Class::Sse + abi::Int(..) | + abi::Pointer => Class::Int, + abi::F32 | + abi::F64 => Class::Sse } } - layout::Abi::Vector { .. } => Class::Sse, + Abi::Vector { .. } => Class::Sse, - layout::Abi::ScalarPair(..) | - layout::Abi::Aggregate { .. } => { + Abi::ScalarPair(..) | + Abi::Aggregate { .. } => { match layout.variants { - layout::Variants::Single { .. } => { + abi::Variants::Single { .. } => { for i in 0..layout.fields.count() { let field_off = off + layout.fields.offset(i); classify(cx, layout.field(cx, i), cls, field_off)?; } return Ok(()); } - layout::Variants::Tagged { .. } | - layout::Variants::NicheFilling { .. } => return Err(Memory), + abi::Variants::Tagged { .. } | + abi::Variants::NicheFilling { .. } => return Err(Memory), } } @@ -160,7 +161,7 @@ fn reg_component(cls: &[Option], i: &mut usize, size: Size) -> Option bug!("reg_component: unhandled class {:?}", c) + Some(c) => unreachable!("reg_component: unhandled class {:?}", c) } } @@ -178,11 +179,14 @@ fn cast_target(cls: &[Option], size: Size) -> CastTarget { target } -pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ let mut int_regs = 6; // RDI, RSI, RDX, RCX, R8, R9 let mut sse_regs = 8; // XMM0-7 - let mut x86_64_ty = |arg: &mut ArgType<'tcx>, is_arg: bool| { + let mut x86_64_ty = |arg: &mut ArgType<'a, Ty>, is_arg: bool| { let mut cls_or_mem = classify_arg(cx, arg); let mut needed_int = 0; diff --git a/src/librustc_trans/cabi_x86_win64.rs b/src/librustc_target/abi/call/x86_win64.rs similarity index 79% rename from src/librustc_trans/cabi_x86_win64.rs rename to src/librustc_target/abi/call/x86_win64.rs index eb5ec4034904b..1ee069e2bbbbf 100644 --- a/src/librustc_trans/cabi_x86_win64.rs +++ b/src/librustc_target/abi/call/x86_win64.rs @@ -8,18 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{ArgType, FnType, Reg}; - -use rustc::ty::layout; +use abi::call::{ArgType, FnType, Reg}; +use abi::Abi; // Win64 ABI: http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx -pub fn compute_abi_info(fty: &mut FnType) { - let fixup = |a: &mut ArgType| { +pub fn compute_abi_info(fty: &mut FnType) { + let fixup = |a: &mut ArgType| { match a.layout.abi { - layout::Abi::Uninhabited => {} - layout::Abi::ScalarPair(..) | - layout::Abi::Aggregate { .. } => { + Abi::Uninhabited => {} + Abi::ScalarPair(..) | + Abi::Aggregate { .. } => { match a.layout.size.bits() { 8 => a.cast_to(Reg::i8()), 16 => a.cast_to(Reg::i16()), @@ -28,11 +27,11 @@ pub fn compute_abi_info(fty: &mut FnType) { _ => a.make_indirect() } } - layout::Abi::Vector { .. } => { + Abi::Vector { .. } => { // FIXME(eddyb) there should be a size cap here // (probably what clang calls "illegal vectors"). } - layout::Abi::Scalar(_) => { + Abi::Scalar(_) => { if a.layout.size.bytes() > 8 { a.make_indirect(); } else { diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs new file mode 100644 index 0000000000000..18dd04c0ee867 --- /dev/null +++ b/src/librustc_target/abi/mod.rs @@ -0,0 +1,823 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub use self::Integer::*; +pub use self::Primitive::*; + +use spec::Target; + +use std::cmp; +use std::ops::{Add, Deref, Sub, Mul, AddAssign, RangeInclusive}; + +pub mod call; + +/// Parsed [Data layout](http://llvm.org/docs/LangRef.html#data-layout) +/// for a target, which contains everything needed to compute layouts. +pub struct TargetDataLayout { + pub endian: Endian, + pub i1_align: Align, + pub i8_align: Align, + pub i16_align: Align, + pub i32_align: Align, + pub i64_align: Align, + pub i128_align: Align, + pub f32_align: Align, + pub f64_align: Align, + pub pointer_size: Size, + pub pointer_align: Align, + pub aggregate_align: Align, + + /// Alignments for vector types. + pub vector_align: Vec<(Size, Align)> +} + +impl Default for TargetDataLayout { + /// Creates an instance of `TargetDataLayout`. + fn default() -> TargetDataLayout { + TargetDataLayout { + endian: Endian::Big, + i1_align: Align::from_bits(8, 8).unwrap(), + i8_align: Align::from_bits(8, 8).unwrap(), + i16_align: Align::from_bits(16, 16).unwrap(), + i32_align: Align::from_bits(32, 32).unwrap(), + i64_align: Align::from_bits(32, 64).unwrap(), + i128_align: Align::from_bits(32, 64).unwrap(), + f32_align: Align::from_bits(32, 32).unwrap(), + f64_align: Align::from_bits(64, 64).unwrap(), + pointer_size: Size::from_bits(64), + pointer_align: Align::from_bits(64, 64).unwrap(), + aggregate_align: Align::from_bits(0, 64).unwrap(), + vector_align: vec![ + (Size::from_bits(64), Align::from_bits(64, 64).unwrap()), + (Size::from_bits(128), Align::from_bits(128, 128).unwrap()) + ] + } + } +} + +impl TargetDataLayout { + pub fn parse(target: &Target) -> Result { + // Parse a bit count from a string. + let parse_bits = |s: &str, kind: &str, cause: &str| { + s.parse::().map_err(|err| { + format!("invalid {} `{}` for `{}` in \"data-layout\": {}", + kind, s, cause, err) + }) + }; + + // Parse a size string. + let size = |s: &str, cause: &str| { + parse_bits(s, "size", cause).map(Size::from_bits) + }; + + // Parse an alignment string. + let align = |s: &[&str], cause: &str| { + if s.is_empty() { + return Err(format!("missing alignment for `{}` in \"data-layout\"", cause)); + } + let abi = parse_bits(s[0], "alignment", cause)?; + let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?; + Align::from_bits(abi, pref).map_err(|err| { + format!("invalid alignment for `{}` in \"data-layout\": {}", + cause, err) + }) + }; + + let mut dl = TargetDataLayout::default(); + let mut i128_align_src = 64; + for spec in target.data_layout.split("-") { + match &spec.split(":").collect::>()[..] { + &["e"] => dl.endian = Endian::Little, + &["E"] => dl.endian = Endian::Big, + &["a", ref a..] => dl.aggregate_align = align(a, "a")?, + &["f32", ref a..] => dl.f32_align = align(a, "f32")?, + &["f64", ref a..] => dl.f64_align = align(a, "f64")?, + &[p @ "p", s, ref a..] | &[p @ "p0", s, ref a..] => { + dl.pointer_size = size(s, p)?; + dl.pointer_align = align(a, p)?; + } + &[s, ref a..] if s.starts_with("i") => { + let bits = match s[1..].parse::() { + Ok(bits) => bits, + Err(_) => { + size(&s[1..], "i")?; // For the user error. + continue; + } + }; + let a = align(a, s)?; + match bits { + 1 => dl.i1_align = a, + 8 => dl.i8_align = a, + 16 => dl.i16_align = a, + 32 => dl.i32_align = a, + 64 => dl.i64_align = a, + _ => {} + } + if bits >= i128_align_src && bits <= 128 { + // Default alignment for i128 is decided by taking the alignment of + // largest-sized i{64...128}. + i128_align_src = bits; + dl.i128_align = a; + } + } + &[s, ref a..] if s.starts_with("v") => { + let v_size = size(&s[1..], "v")?; + let a = align(a, s)?; + if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) { + v.1 = a; + continue; + } + // No existing entry, add a new one. + dl.vector_align.push((v_size, a)); + } + _ => {} // Ignore everything else. + } + } + + // Perform consistency checks against the Target information. + let endian_str = match dl.endian { + Endian::Little => "little", + Endian::Big => "big" + }; + if endian_str != target.target_endian { + return Err(format!("inconsistent target specification: \"data-layout\" claims \ + architecture is {}-endian, while \"target-endian\" is `{}`", + endian_str, target.target_endian)); + } + + if dl.pointer_size.bits().to_string() != target.target_pointer_width { + return Err(format!("inconsistent target specification: \"data-layout\" claims \ + pointers are {}-bit, while \"target-pointer-width\" is `{}`", + dl.pointer_size.bits(), target.target_pointer_width)); + } + + Ok(dl) + } + + /// Return exclusive upper bound on object size. + /// + /// The theoretical maximum object size is defined as the maximum positive `isize` value. + /// This ensures that the `offset` semantics remain well-defined by allowing it to correctly + /// index every address within an object along with one byte past the end, along with allowing + /// `isize` to store the difference between any two pointers into an object. + /// + /// The upper bound on 64-bit currently needs to be lower because LLVM uses a 64-bit integer + /// to represent object size in bits. It would need to be 1 << 61 to account for this, but is + /// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable + /// address space on 64-bit ARMv8 and x86_64. + pub fn obj_size_bound(&self) -> u64 { + match self.pointer_size.bits() { + 16 => 1 << 15, + 32 => 1 << 31, + 64 => 1 << 47, + bits => panic!("obj_size_bound: unknown pointer bit size {}", bits) + } + } + + pub fn ptr_sized_integer(&self) -> Integer { + match self.pointer_size.bits() { + 16 => I16, + 32 => I32, + 64 => I64, + bits => panic!("ptr_sized_integer: unknown pointer bit size {}", bits) + } + } + + pub fn vector_align(&self, vec_size: Size) -> Align { + for &(size, align) in &self.vector_align { + if size == vec_size { + return align; + } + } + // Default to natural alignment, which is what LLVM does. + // That is, use the size, rounded up to a power of 2. + let align = vec_size.bytes().next_power_of_two(); + Align::from_bytes(align, align).unwrap() + } +} + +pub trait HasDataLayout: Copy { + fn data_layout(&self) -> &TargetDataLayout; +} + +impl<'a> HasDataLayout for &'a TargetDataLayout { + fn data_layout(&self) -> &TargetDataLayout { + self + } +} + +/// Endianness of the target, which must match cfg(target-endian). +#[derive(Copy, Clone)] +pub enum Endian { + Little, + Big +} + +/// Size of a type in bytes. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub struct Size { + raw: u64 +} + +impl Size { + pub fn from_bits(bits: u64) -> Size { + // Avoid potential overflow from `bits + 7`. + Size::from_bytes(bits / 8 + ((bits % 8) + 7) / 8) + } + + pub fn from_bytes(bytes: u64) -> Size { + if bytes >= (1 << 61) { + panic!("Size::from_bytes: {} bytes in bits doesn't fit in u64", bytes) + } + Size { + raw: bytes + } + } + + pub fn bytes(self) -> u64 { + self.raw + } + + pub fn bits(self) -> u64 { + self.bytes() * 8 + } + + pub fn abi_align(self, align: Align) -> Size { + let mask = align.abi() - 1; + Size::from_bytes((self.bytes() + mask) & !mask) + } + + pub fn is_abi_aligned(self, align: Align) -> bool { + let mask = align.abi() - 1; + self.bytes() & mask == 0 + } + + pub fn checked_add(self, offset: Size, cx: C) -> Option { + let dl = cx.data_layout(); + + // Each Size is less than dl.obj_size_bound(), so the sum is + // also less than 1 << 62 (and therefore can't overflow). + let bytes = self.bytes() + offset.bytes(); + + if bytes < dl.obj_size_bound() { + Some(Size::from_bytes(bytes)) + } else { + None + } + } + + pub fn checked_mul(self, count: u64, cx: C) -> Option { + let dl = cx.data_layout(); + + match self.bytes().checked_mul(count) { + Some(bytes) if bytes < dl.obj_size_bound() => { + Some(Size::from_bytes(bytes)) + } + _ => None + } + } +} + +// Panicking addition, subtraction and multiplication for convenience. +// Avoid during layout computation, return `LayoutError` instead. + +impl Add for Size { + type Output = Size; + fn add(self, other: Size) -> Size { + // Each Size is less than 1 << 61, so the sum is + // less than 1 << 62 (and therefore can't overflow). + Size::from_bytes(self.bytes() + other.bytes()) + } +} + +impl Sub for Size { + type Output = Size; + fn sub(self, other: Size) -> Size { + // Each Size is less than 1 << 61, so an underflow + // would result in a value larger than 1 << 61, + // which Size::from_bytes will catch for us. + Size::from_bytes(self.bytes() - other.bytes()) + } +} + +impl Mul for Size { + type Output = Size; + fn mul(self, count: u64) -> Size { + match self.bytes().checked_mul(count) { + Some(bytes) => Size::from_bytes(bytes), + None => { + panic!("Size::mul: {} * {} doesn't fit in u64", self.bytes(), count) + } + } + } +} + +impl AddAssign for Size { + fn add_assign(&mut self, other: Size) { + *self = *self + other; + } +} + +/// Alignment of a type in bytes, both ABI-mandated and preferred. +/// Each field is a power of two, giving the alignment a maximum value of +/// 2(28 - 1), which is limited by LLVM to a i32, +/// with a maximum capacity of 231 - 1 or 2147483647. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] +pub struct Align { + abi_pow2: u8, + pref_pow2: u8, +} + +impl Align { + pub fn from_bits(abi: u64, pref: u64) -> Result { + Align::from_bytes(Size::from_bits(abi).bytes(), + Size::from_bits(pref).bytes()) + } + + pub fn from_bytes(abi: u64, pref: u64) -> Result { + let log2 = |align: u64| { + // Treat an alignment of 0 bytes like 1-byte alignment. + if align == 0 { + return Ok(0); + } + + let mut bytes = align; + let mut pow: u8 = 0; + while (bytes & 1) == 0 { + pow += 1; + bytes >>= 1; + } + if bytes != 1 { + Err(format!("`{}` is not a power of 2", align)) + } else if pow > 30 { + Err(format!("`{}` is too large", align)) + } else { + Ok(pow) + } + }; + + Ok(Align { + abi_pow2: log2(abi)?, + pref_pow2: log2(pref)?, + }) + } + + pub fn abi(self) -> u64 { + 1 << self.abi_pow2 + } + + pub fn pref(self) -> u64 { + 1 << self.pref_pow2 + } + + pub fn abi_bits(self) -> u64 { + self.abi() * 8 + } + + pub fn pref_bits(self) -> u64 { + self.pref() * 8 + } + + pub fn min(self, other: Align) -> Align { + Align { + abi_pow2: cmp::min(self.abi_pow2, other.abi_pow2), + pref_pow2: cmp::min(self.pref_pow2, other.pref_pow2), + } + } + + pub fn max(self, other: Align) -> Align { + Align { + abi_pow2: cmp::max(self.abi_pow2, other.abi_pow2), + pref_pow2: cmp::max(self.pref_pow2, other.pref_pow2), + } + } +} + +/// Integers, also used for enum discriminants. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub enum Integer { + I8, + I16, + I32, + I64, + I128, +} + +impl Integer { + pub fn size(&self) -> Size { + match *self { + I8 => Size::from_bytes(1), + I16 => Size::from_bytes(2), + I32 => Size::from_bytes(4), + I64 => Size::from_bytes(8), + I128 => Size::from_bytes(16), + } + } + + pub fn align(&self, cx: C) -> Align { + let dl = cx.data_layout(); + + match *self { + I8 => dl.i8_align, + I16 => dl.i16_align, + I32 => dl.i32_align, + I64 => dl.i64_align, + I128 => dl.i128_align, + } + } + + /// Find the smallest Integer type which can represent the signed value. + pub fn fit_signed(x: i128) -> Integer { + match x { + -0x0000_0000_0000_0080...0x0000_0000_0000_007f => I8, + -0x0000_0000_0000_8000...0x0000_0000_0000_7fff => I16, + -0x0000_0000_8000_0000...0x0000_0000_7fff_ffff => I32, + -0x8000_0000_0000_0000...0x7fff_ffff_ffff_ffff => I64, + _ => I128 + } + } + + /// Find the smallest Integer type which can represent the unsigned value. + pub fn fit_unsigned(x: u128) -> Integer { + match x { + 0...0x0000_0000_0000_00ff => I8, + 0...0x0000_0000_0000_ffff => I16, + 0...0x0000_0000_ffff_ffff => I32, + 0...0xffff_ffff_ffff_ffff => I64, + _ => I128, + } + } + + /// Find the smallest integer with the given alignment. + pub fn for_abi_align(cx: C, align: Align) -> Option { + let dl = cx.data_layout(); + + let wanted = align.abi(); + for &candidate in &[I8, I16, I32, I64, I128] { + if wanted == candidate.align(dl).abi() && wanted == candidate.size().bytes() { + return Some(candidate); + } + } + None + } + + /// Find the largest integer with the given alignment or less. + pub fn approximate_abi_align(cx: C, align: Align) -> Integer { + let dl = cx.data_layout(); + + let wanted = align.abi(); + // FIXME(eddyb) maybe include I128 in the future, when it works everywhere. + for &candidate in &[I64, I32, I16] { + if wanted >= candidate.align(dl).abi() && wanted >= candidate.size().bytes() { + return candidate; + } + } + I8 + } +} + +/// Fundamental unit of memory access and layout. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum Primitive { + /// The `bool` is the signedness of the `Integer` type. + /// + /// One would think we would not care about such details this low down, + /// but some ABIs are described in terms of C types and ISAs where the + /// integer arithmetic is done on {sign,zero}-extended registers, e.g. + /// a negative integer passed by zero-extension will appear positive in + /// the callee, and most operations on it will produce the wrong values. + Int(Integer, bool), + F32, + F64, + Pointer +} + +impl<'a, 'tcx> Primitive { + pub fn size(self, cx: C) -> Size { + let dl = cx.data_layout(); + + match self { + Int(i, _) => i.size(), + F32 => Size::from_bits(32), + F64 => Size::from_bits(64), + Pointer => dl.pointer_size + } + } + + pub fn align(self, cx: C) -> Align { + let dl = cx.data_layout(); + + match self { + Int(i, _) => i.align(dl), + F32 => dl.f32_align, + F64 => dl.f64_align, + Pointer => dl.pointer_align + } + } +} + +/// Information about one scalar component of a Rust type. +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct Scalar { + pub value: Primitive, + + /// Inclusive wrap-around range of valid values, that is, if + /// min > max, it represents min..=u128::MAX followed by 0..=max. + // FIXME(eddyb) always use the shortest range, e.g. by finding + // the largest space between two consecutive valid values and + // taking everything else as the (shortest) valid range. + pub valid_range: RangeInclusive, +} + +impl Scalar { + pub fn is_bool(&self) -> bool { + if let Int(I8, _) = self.value { + self.valid_range == (0..=1) + } else { + false + } + } +} + +/// Describes how the fields of a type are located in memory. +#[derive(PartialEq, Eq, Hash, Debug)] +pub enum FieldPlacement { + /// All fields start at no offset. The `usize` is the field count. + Union(usize), + + /// Array/vector-like placement, with all fields of identical types. + Array { + stride: Size, + count: u64 + }, + + /// Struct-like placement, with precomputed offsets. + /// + /// Fields are guaranteed to not overlap, but note that gaps + /// before, between and after all the fields are NOT always + /// padding, and as such their contents may not be discarded. + /// For example, enum variants leave a gap at the start, + /// where the discriminant field in the enum layout goes. + Arbitrary { + /// Offsets for the first byte of each field, + /// ordered to match the source definition order. + /// This vector does not go in increasing order. + // FIXME(eddyb) use small vector optimization for the common case. + offsets: Vec, + + /// Maps source order field indices to memory order indices, + /// depending how fields were permuted. + // FIXME(camlorn) also consider small vector optimization here. + memory_index: Vec + } +} + +impl FieldPlacement { + pub fn count(&self) -> usize { + match *self { + FieldPlacement::Union(count) => count, + FieldPlacement::Array { count, .. } => { + let usize_count = count as usize; + assert_eq!(usize_count as u64, count); + usize_count + } + FieldPlacement::Arbitrary { ref offsets, .. } => offsets.len() + } + } + + pub fn offset(&self, i: usize) -> Size { + match *self { + FieldPlacement::Union(_) => Size::from_bytes(0), + FieldPlacement::Array { stride, count } => { + let i = i as u64; + assert!(i < count); + stride * i + } + FieldPlacement::Arbitrary { ref offsets, .. } => offsets[i] + } + } + + pub fn memory_index(&self, i: usize) -> usize { + match *self { + FieldPlacement::Union(_) | + FieldPlacement::Array { .. } => i, + FieldPlacement::Arbitrary { ref memory_index, .. } => { + let r = memory_index[i]; + assert_eq!(r as usize as u32, r); + r as usize + } + } + } + + /// Get source indices of the fields by increasing offsets. + #[inline] + pub fn index_by_increasing_offset<'a>(&'a self) -> impl Iterator+'a { + let mut inverse_small = [0u8; 64]; + let mut inverse_big = vec![]; + let use_small = self.count() <= inverse_small.len(); + + // We have to write this logic twice in order to keep the array small. + if let FieldPlacement::Arbitrary { ref memory_index, .. } = *self { + if use_small { + for i in 0..self.count() { + inverse_small[memory_index[i] as usize] = i as u8; + } + } else { + inverse_big = vec![0; self.count()]; + for i in 0..self.count() { + inverse_big[memory_index[i] as usize] = i as u32; + } + } + } + + (0..self.count()).map(move |i| { + match *self { + FieldPlacement::Union(_) | + FieldPlacement::Array { .. } => i, + FieldPlacement::Arbitrary { .. } => { + if use_small { inverse_small[i] as usize } + else { inverse_big[i] as usize } + } + } + }) + } +} + +/// Describes how values of the type are passed by target ABIs, +/// in terms of categories of C types there are ABI rules for. +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub enum Abi { + Uninhabited, + Scalar(Scalar), + ScalarPair(Scalar, Scalar), + Vector { + element: Scalar, + count: u64 + }, + Aggregate { + /// If true, the size is exact, otherwise it's only a lower bound. + sized: bool, + } +} + +impl Abi { + /// Returns true if the layout corresponds to an unsized type. + pub fn is_unsized(&self) -> bool { + match *self { + Abi::Uninhabited | + Abi::Scalar(_) | + Abi::ScalarPair(..) | + Abi::Vector { .. } => false, + Abi::Aggregate { sized } => !sized + } + } + + /// Returns true if this is a single signed integer scalar + pub fn is_signed(&self) -> bool { + match *self { + Abi::Scalar(ref scal) => match scal.value { + Primitive::Int(_, signed) => signed, + _ => false, + }, + _ => false, + } + } +} + +#[derive(PartialEq, Eq, Hash, Debug)] +pub enum Variants { + /// Single enum variants, structs/tuples, unions, and all non-ADTs. + Single { + index: usize + }, + + /// General-case enums: for each case there is a struct, and they all have + /// all space reserved for the discriminant, and their first field starts + /// at a non-0 offset, after where the discriminant would go. + Tagged { + discr: Scalar, + variants: Vec, + }, + + /// Multiple cases distinguished by a niche (values invalid for a type): + /// the variant `dataful_variant` contains a niche at an arbitrary + /// offset (field 0 of the enum), which for a variant with discriminant + /// `d` is set to `(d - niche_variants.start).wrapping_add(niche_start)`. + /// + /// For example, `Option<(usize, &T)>` is represented such that + /// `None` has a null pointer for the second tuple field, and + /// `Some` is the identity function (with a non-null reference). + NicheFilling { + dataful_variant: usize, + niche_variants: RangeInclusive, + niche: Scalar, + niche_start: u128, + variants: Vec, + } +} + +#[derive(PartialEq, Eq, Hash, Debug)] +pub struct LayoutDetails { + pub variants: Variants, + pub fields: FieldPlacement, + pub abi: Abi, + pub align: Align, + pub size: Size +} + +impl LayoutDetails { + pub fn scalar(cx: C, scalar: Scalar) -> Self { + let size = scalar.value.size(cx); + let align = scalar.value.align(cx); + LayoutDetails { + variants: Variants::Single { index: 0 }, + fields: FieldPlacement::Union(0), + abi: Abi::Scalar(scalar), + size, + align, + } + } + + pub fn uninhabited(field_count: usize) -> Self { + let align = Align::from_bytes(1, 1).unwrap(); + LayoutDetails { + variants: Variants::Single { index: 0 }, + fields: FieldPlacement::Union(field_count), + abi: Abi::Uninhabited, + align, + size: Size::from_bytes(0) + } + } +} + +/// The details of the layout of a type, alongside the type itself. +/// Provides various type traversal APIs (e.g. recursing into fields). +/// +/// Note that the details are NOT guaranteed to always be identical +/// to those obtained from `layout_of(ty)`, as we need to produce +/// layouts for which Rust types do not exist, such as enum variants +/// or synthetic fields of enums (i.e. discriminants) and fat pointers. +#[derive(Copy, Clone, Debug)] +pub struct TyLayout<'a, Ty> { + pub ty: Ty, + pub details: &'a LayoutDetails +} + +impl<'a, Ty> Deref for TyLayout<'a, Ty> { + type Target = &'a LayoutDetails; + fn deref(&self) -> &&'a LayoutDetails { + &self.details + } +} + +pub trait LayoutOf { + type Ty; + type TyLayout; + + fn layout_of(self, ty: Self::Ty) -> Self::TyLayout; +} + +pub trait TyLayoutMethods<'a, C: LayoutOf>: Sized { + fn for_variant(this: TyLayout<'a, Self>, cx: C, variant_index: usize) -> TyLayout<'a, Self>; + fn field(this: TyLayout<'a, Self>, cx: C, i: usize) -> C::TyLayout; +} + +impl<'a, Ty> TyLayout<'a, Ty> { + pub fn for_variant(self, cx: C, variant_index: usize) -> Self + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf { + Ty::for_variant(self, cx, variant_index) + } + pub fn field(self, cx: C, i: usize) -> C::TyLayout + where Ty: TyLayoutMethods<'a, C>, C: LayoutOf { + Ty::field(self, cx, i) + } +} + +impl<'a, Ty> TyLayout<'a, Ty> { + /// Returns true if the layout corresponds to an unsized type. + pub fn is_unsized(&self) -> bool { + self.abi.is_unsized() + } + + /// Returns true if the type is a ZST and not unsized. + pub fn is_zst(&self) -> bool { + match self.abi { + Abi::Uninhabited => true, + Abi::Scalar(_) | + Abi::ScalarPair(..) | + Abi::Vector { .. } => false, + Abi::Aggregate { sized } => sized && self.size.bytes() == 0 + } + } + + pub fn size_and_align(&self) -> (Size, Align) { + (self.size, self.align) + } +} diff --git a/src/librustc_back/build.rs b/src/librustc_target/build.rs similarity index 100% rename from src/librustc_back/build.rs rename to src/librustc_target/build.rs diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs new file mode 100644 index 0000000000000..8f4911574398b --- /dev/null +++ b/src/librustc_target/lib.rs @@ -0,0 +1,46 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Some stuff used by rustc that doesn't have many dependencies +//! +//! Originally extracted from rustc::back, which was nominally the +//! compiler 'backend', though LLVM is rustc's backend, so rustc_target +//! is really just odds-and-ends relating to code gen and linking. +//! This crate mostly exists to make rustc smaller, so we might put +//! more 'stuff' here in the future. It does not have a dependency on +//! rustc_llvm. +//! +//! FIXME: Split this into two crates: one that has deps on syntax, and +//! one that doesn't; the one that doesn't might get decent parallel +//! build speedups. + +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/")] + +#![feature(box_syntax)] +#![feature(const_fn)] +#![feature(fs_read_write)] +#![feature(inclusive_range)] +#![feature(slice_patterns)] + +#[macro_use] +extern crate bitflags; +extern crate serialize; +#[macro_use] extern crate log; + +extern crate serialize as rustc_serialize; // used by deriving + +// See librustc_cratesio_shim/Cargo.toml for a comment explaining this. +#[allow(unused_extern_crates)] +extern crate rustc_cratesio_shim; + +pub mod abi; +pub mod spec; diff --git a/src/librustc_back/target/aarch64_apple_ios.rs b/src/librustc_target/spec/aarch64_apple_ios.rs similarity index 95% rename from src/librustc_back/target/aarch64_apple_ios.rs rename to src/librustc_target/spec/aarch64_apple_ios.rs index cff6eb534b1e5..90f8cd90c66ec 100644 --- a/src/librustc_back/target/aarch64_apple_ios.rs +++ b/src/librustc_target/spec/aarch64_apple_ios.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_back/target/aarch64_linux_android.rs b/src/librustc_target/spec/aarch64_linux_android.rs similarity index 95% rename from src/librustc_back/target/aarch64_linux_android.rs rename to src/librustc_target/spec/aarch64_linux_android.rs index 2c0d6a55ed8e5..afd67112f0d6a 100644 --- a/src/librustc_back/target/aarch64_linux_android.rs +++ b/src/librustc_target/spec/aarch64_linux_android.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a // for target ABI requirements. diff --git a/src/librustc_back/target/aarch64_unknown_cloudabi.rs b/src/librustc_target/spec/aarch64_unknown_cloudabi.rs similarity index 95% rename from src/librustc_back/target/aarch64_unknown_cloudabi.rs rename to src/librustc_target/spec/aarch64_unknown_cloudabi.rs index a5d0e5bf166dd..ffdb7decd0b47 100644 --- a/src/librustc_back/target/aarch64_unknown_cloudabi.rs +++ b/src/librustc_target/spec/aarch64_unknown_cloudabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); diff --git a/src/librustc_back/target/aarch64_unknown_freebsd.rs b/src/librustc_target/spec/aarch64_unknown_freebsd.rs similarity index 94% rename from src/librustc_back/target/aarch64_unknown_freebsd.rs rename to src/librustc_target/spec/aarch64_unknown_freebsd.rs index 1ce8d600c0331..48177b8c79aed 100644 --- a/src/librustc_back/target/aarch64_unknown_freebsd.rs +++ b/src/librustc_target/spec/aarch64_unknown_freebsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); diff --git a/src/librustc_back/target/aarch64_unknown_fuchsia.rs b/src/librustc_target/spec/aarch64_unknown_fuchsia.rs similarity index 94% rename from src/librustc_back/target/aarch64_unknown_fuchsia.rs rename to src/librustc_target/spec/aarch64_unknown_fuchsia.rs index 73cd9c9270153..4da6724ef6286 100644 --- a/src/librustc_back/target/aarch64_unknown_fuchsia.rs +++ b/src/librustc_target/spec/aarch64_unknown_fuchsia.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::fuchsia_base::opts(); diff --git a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs b/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs similarity index 94% rename from src/librustc_back/target/aarch64_unknown_linux_gnu.rs rename to src/librustc_target/spec/aarch64_unknown_linux_gnu.rs index 5c9c9a0c555c2..2351d01469215 100644 --- a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/aarch64_unknown_linux_musl.rs b/src/librustc_target/spec/aarch64_unknown_linux_musl.rs similarity index 94% rename from src/librustc_back/target/aarch64_unknown_linux_musl.rs rename to src/librustc_target/spec/aarch64_unknown_linux_musl.rs index d39ad97bbcb87..5ab55a076f45b 100644 --- a/src/librustc_back/target/aarch64_unknown_linux_musl.rs +++ b/src/librustc_target/spec/aarch64_unknown_linux_musl.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/libsyntax/abi.rs b/src/librustc_target/spec/abi.rs similarity index 100% rename from src/libsyntax/abi.rs rename to src/librustc_target/spec/abi.rs diff --git a/src/librustc_back/target/android_base.rs b/src/librustc_target/spec/android_base.rs similarity index 95% rename from src/librustc_back/target/android_base.rs rename to src/librustc_target/spec/android_base.rs index 3660bf7bea917..7e27e8aa9a76b 100644 --- a/src/librustc_back/target/android_base.rs +++ b/src/librustc_target/spec/android_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::TargetOptions; +use spec::{LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/apple_base.rs b/src/librustc_target/spec/apple_base.rs similarity index 98% rename from src/librustc_back/target/apple_base.rs rename to src/librustc_target/spec/apple_base.rs index 480de9ff486e5..4b66891e36f8c 100644 --- a/src/librustc_back/target/apple_base.rs +++ b/src/librustc_target/spec/apple_base.rs @@ -10,7 +10,7 @@ use std::env; -use target::{LinkArgs, TargetOptions}; +use spec::{LinkArgs, TargetOptions}; pub fn opts() -> TargetOptions { // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6 diff --git a/src/librustc_back/target/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs similarity index 98% rename from src/librustc_back/target/apple_ios_base.rs rename to src/librustc_target/spec/apple_ios_base.rs index 1895ab1eb7e78..acbbab313fe59 100644 --- a/src/librustc_back/target/apple_ios_base.rs +++ b/src/librustc_target/spec/apple_ios_base.rs @@ -8,10 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; use std::io; use std::process::Command; -use target::{LinkArgs, TargetOptions}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions}; use self::Arch::*; diff --git a/src/librustc_back/target/arm_base.rs b/src/librustc_target/spec/arm_base.rs similarity index 96% rename from src/librustc_back/target/arm_base.rs rename to src/librustc_target/spec/arm_base.rs index 416e5a0e13a88..635b8ae7388fe 100644 --- a/src/librustc_back/target/arm_base.rs +++ b/src/librustc_target/spec/arm_base.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use syntax::abi::Abi; +use spec::abi::Abi; // All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm pub fn abi_blacklist() -> Vec { diff --git a/src/librustc_back/target/arm_linux_androideabi.rs b/src/librustc_target/spec/arm_linux_androideabi.rs similarity index 95% rename from src/librustc_back/target/arm_linux_androideabi.rs rename to src/librustc_target/spec/arm_linux_androideabi.rs index ba21b1df032a8..ffd242b2bc20e 100644 --- a/src/librustc_back/target/arm_linux_androideabi.rs +++ b/src/librustc_target/spec/arm_linux_androideabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::android_base::opts(); diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs similarity index 94% rename from src/librustc_back/target/arm_unknown_linux_gnueabi.rs rename to src/librustc_target/spec/arm_unknown_linux_gnueabi.rs index e630376a67dd0..c67a25e8bc275 100644 --- a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs similarity index 94% rename from src/librustc_back/target/arm_unknown_linux_gnueabihf.rs rename to src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs index 178a948b2b9c8..ed0049a932e92 100644 --- a/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_target/spec/arm_unknown_linux_musleabi.rs similarity index 95% rename from src/librustc_back/target/arm_unknown_linux_musleabi.rs rename to src/librustc_target/spec/arm_unknown_linux_musleabi.rs index 29720ec5efcd7..c34093fbab912 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabi.rs +++ b/src/librustc_target/spec/arm_unknown_linux_musleabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs similarity index 95% rename from src/librustc_back/target/arm_unknown_linux_musleabihf.rs rename to src/librustc_target/spec/arm_unknown_linux_musleabihf.rs index fc8313877f640..967873b3201b5 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_back/target/armv4t_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs similarity index 95% rename from src/librustc_back/target/armv4t_unknown_linux_gnueabi.rs rename to src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs index 33399a7849367..fb99dffeddd69 100644 --- a/src/librustc_back/target/armv4t_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let base = super::linux_base::opts(); diff --git a/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs similarity index 95% rename from src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs rename to src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs index 4efe66980a03b..810f091247224 100644 --- a/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let base = super::linux_base::opts(); diff --git a/src/librustc_back/target/armv7_apple_ios.rs b/src/librustc_target/spec/armv7_apple_ios.rs similarity index 94% rename from src/librustc_back/target/armv7_apple_ios.rs rename to src/librustc_target/spec/armv7_apple_ios.rs index 67d3d12fb5776..da7cbb918bd71 100644 --- a/src/librustc_back/target/armv7_apple_ios.rs +++ b/src/librustc_target/spec/armv7_apple_ios.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_back/target/armv7_linux_androideabi.rs b/src/librustc_target/spec/armv7_linux_androideabi.rs similarity index 95% rename from src/librustc_back/target/armv7_linux_androideabi.rs rename to src/librustc_target/spec/armv7_linux_androideabi.rs index 9e3eec13ab763..cfdc5cddcfb30 100644 --- a/src/librustc_back/target/armv7_linux_androideabi.rs +++ b/src/librustc_target/spec/armv7_linux_androideabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; // See https://developer.android.com/ndk/guides/abis.html#v7a // for target ABI requirements. diff --git a/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs b/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs similarity index 96% rename from src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs rename to src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs index fa66a35abbf35..393c45e434e61 100644 --- a/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); diff --git a/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs similarity index 95% rename from src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs rename to src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs index 569c721473da5..14e8fa9dc02a4 100644 --- a/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let base = super::linux_base::opts(); diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs similarity index 95% rename from src/librustc_back/target/armv7_unknown_linux_musleabihf.rs rename to src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs index 88f2b59675186..6e71cb307b997 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let base = super::linux_musl_base::opts(); diff --git a/src/librustc_back/target/armv7s_apple_ios.rs b/src/librustc_target/spec/armv7s_apple_ios.rs similarity index 94% rename from src/librustc_back/target/armv7s_apple_ios.rs rename to src/librustc_target/spec/armv7s_apple_ios.rs index e4cc89ab21140..c0c577c3b8c6c 100644 --- a/src/librustc_back/target/armv7s_apple_ios.rs +++ b/src/librustc_target/spec/armv7s_apple_ios.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_back/target/asmjs_unknown_emscripten.rs b/src/librustc_target/spec/asmjs_unknown_emscripten.rs similarity index 96% rename from src/librustc_back/target/asmjs_unknown_emscripten.rs rename to src/librustc_target/spec/asmjs_unknown_emscripten.rs index ab7df4ba1c543..e2cf714f0ead3 100644 --- a/src/librustc_back/target/asmjs_unknown_emscripten.rs +++ b/src/librustc_target/spec/asmjs_unknown_emscripten.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use super::{LinkArgs, Target, TargetOptions}; +use super::{LinkArgs, LinkerFlavor, Target, TargetOptions}; pub fn target() -> Result { let mut args = LinkArgs::new(); diff --git a/src/librustc_back/target/bitrig_base.rs b/src/librustc_target/spec/bitrig_base.rs similarity index 95% rename from src/librustc_back/target/bitrig_base.rs rename to src/librustc_target/spec/bitrig_base.rs index 45ceb2d5a6046..e0cbfcdcef07c 100644 --- a/src/librustc_back/target/bitrig_base.rs +++ b/src/librustc_target/spec/bitrig_base.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::{TargetOptions, RelroLevel}; +use spec::{TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/cloudabi_base.rs b/src/librustc_target/spec/cloudabi_base.rs similarity index 94% rename from src/librustc_back/target/cloudabi_base.rs rename to src/librustc_target/spec/cloudabi_base.rs index 4cd52ebb26df5..2ffa74e737fd5 100644 --- a/src/librustc_back/target/cloudabi_base.rs +++ b/src/librustc_target/spec/cloudabi_base.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions, RelroLevel}; -use std::default::Default; +use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_back/target/dragonfly_base.rs b/src/librustc_target/spec/dragonfly_base.rs similarity index 95% rename from src/librustc_back/target/dragonfly_base.rs rename to src/librustc_target/spec/dragonfly_base.rs index 21dca99aa5005..32eac8663afac 100644 --- a/src/librustc_back/target/dragonfly_base.rs +++ b/src/librustc_target/spec/dragonfly_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions, RelroLevel}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/freebsd_base.rs b/src/librustc_target/spec/freebsd_base.rs similarity index 95% rename from src/librustc_back/target/freebsd_base.rs rename to src/librustc_target/spec/freebsd_base.rs index 291b22768998c..04b8a6e706064 100644 --- a/src/librustc_back/target/freebsd_base.rs +++ b/src/librustc_target/spec/freebsd_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions, RelroLevel}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs similarity index 96% rename from src/librustc_back/target/fuchsia_base.rs rename to src/librustc_target/spec/fuchsia_base.rs index 63ccd21c220f3..19a66b693f256 100644 --- a/src/librustc_back/target/fuchsia_base.rs +++ b/src/librustc_target/spec/fuchsia_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/haiku_base.rs b/src/librustc_target/spec/haiku_base.rs similarity index 95% rename from src/librustc_back/target/haiku_base.rs rename to src/librustc_target/spec/haiku_base.rs index a1ccb632cab79..bf62b49f9141b 100644 --- a/src/librustc_back/target/haiku_base.rs +++ b/src/librustc_target/spec/haiku_base.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::{TargetOptions, RelroLevel}; +use spec::{TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/i386_apple_ios.rs b/src/librustc_target/spec/i386_apple_ios.rs similarity index 94% rename from src/librustc_back/target/i386_apple_ios.rs rename to src/librustc_target/spec/i386_apple_ios.rs index 82eae1a31a9ad..9eb0327f625cc 100644 --- a/src/librustc_back/target/i386_apple_ios.rs +++ b/src/librustc_target/spec/i386_apple_ios.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_back/target/i586_pc_windows_msvc.rs b/src/librustc_target/spec/i586_pc_windows_msvc.rs similarity index 96% rename from src/librustc_back/target/i586_pc_windows_msvc.rs rename to src/librustc_target/spec/i586_pc_windows_msvc.rs index 9b88cde598937..9a20b854e0f41 100644 --- a/src/librustc_back/target/i586_pc_windows_msvc.rs +++ b/src/librustc_target/spec/i586_pc_windows_msvc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetResult; +use spec::TargetResult; pub fn target() -> TargetResult { let mut base = super::i686_pc_windows_msvc::target()?; diff --git a/src/librustc_back/target/i586_unknown_linux_gnu.rs b/src/librustc_target/spec/i586_unknown_linux_gnu.rs similarity index 96% rename from src/librustc_back/target/i586_unknown_linux_gnu.rs rename to src/librustc_target/spec/i586_unknown_linux_gnu.rs index 40fb4a67acdf1..35bca76af47df 100644 --- a/src/librustc_back/target/i586_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/i586_unknown_linux_gnu.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetResult; +use spec::TargetResult; pub fn target() -> TargetResult { let mut base = super::i686_unknown_linux_gnu::target()?; diff --git a/src/librustc_back/target/i586_unknown_linux_musl.rs b/src/librustc_target/spec/i586_unknown_linux_musl.rs similarity index 96% rename from src/librustc_back/target/i586_unknown_linux_musl.rs rename to src/librustc_target/spec/i586_unknown_linux_musl.rs index 416eacf475b5c..ba23e1d6860bd 100644 --- a/src/librustc_back/target/i586_unknown_linux_musl.rs +++ b/src/librustc_target/spec/i586_unknown_linux_musl.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetResult; +use spec::TargetResult; pub fn target() -> TargetResult { let mut base = super::i686_unknown_linux_musl::target()?; diff --git a/src/librustc_back/target/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs similarity index 95% rename from src/librustc_back/target/i686_apple_darwin.rs rename to src/librustc_target/spec/i686_apple_darwin.rs index 14937f9aa55b6..06ea1e4649b42 100644 --- a/src/librustc_back/target/i686_apple_darwin.rs +++ b/src/librustc_target/spec/i686_apple_darwin.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::apple_base::opts(); diff --git a/src/librustc_back/target/i686_linux_android.rs b/src/librustc_target/spec/i686_linux_android.rs similarity index 96% rename from src/librustc_back/target/i686_linux_android.rs rename to src/librustc_target/spec/i686_linux_android.rs index bf27bce79acec..171e089959545 100644 --- a/src/librustc_back/target/i686_linux_android.rs +++ b/src/librustc_target/spec/i686_linux_android.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; // See https://developer.android.com/ndk/guides/abis.html#x86 // for target ABI requirements. diff --git a/src/librustc_back/target/i686_pc_windows_gnu.rs b/src/librustc_target/spec/i686_pc_windows_gnu.rs similarity index 96% rename from src/librustc_back/target/i686_pc_windows_gnu.rs rename to src/librustc_target/spec/i686_pc_windows_gnu.rs index 5f20a620b6e1c..867d04ec3f28b 100644 --- a/src/librustc_back/target/i686_pc_windows_gnu.rs +++ b/src/librustc_target/spec/i686_pc_windows_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_base::opts(); diff --git a/src/librustc_back/target/i686_pc_windows_msvc.rs b/src/librustc_target/spec/i686_pc_windows_msvc.rs similarity index 96% rename from src/librustc_back/target/i686_pc_windows_msvc.rs rename to src/librustc_target/spec/i686_pc_windows_msvc.rs index 48cee04457348..3570f379c3087 100644 --- a/src/librustc_back/target/i686_pc_windows_msvc.rs +++ b/src/librustc_target/spec/i686_pc_windows_msvc.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); diff --git a/src/librustc_back/target/i686_unknown_cloudabi.rs b/src/librustc_target/spec/i686_unknown_cloudabi.rs similarity index 96% rename from src/librustc_back/target/i686_unknown_cloudabi.rs rename to src/librustc_target/spec/i686_unknown_cloudabi.rs index 69c3b298caba0..335105bb1a869 100644 --- a/src/librustc_back/target/i686_unknown_cloudabi.rs +++ b/src/librustc_target/spec/i686_unknown_cloudabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); diff --git a/src/librustc_back/target/i686_unknown_dragonfly.rs b/src/librustc_target/spec/i686_unknown_dragonfly.rs similarity index 95% rename from src/librustc_back/target/i686_unknown_dragonfly.rs rename to src/librustc_target/spec/i686_unknown_dragonfly.rs index 891127b9d3711..cb0c471353b30 100644 --- a/src/librustc_back/target/i686_unknown_dragonfly.rs +++ b/src/librustc_target/spec/i686_unknown_dragonfly.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::dragonfly_base::opts(); diff --git a/src/librustc_back/target/i686_unknown_freebsd.rs b/src/librustc_target/spec/i686_unknown_freebsd.rs similarity index 95% rename from src/librustc_back/target/i686_unknown_freebsd.rs rename to src/librustc_target/spec/i686_unknown_freebsd.rs index 076acb8ed318c..3838a157d10b5 100644 --- a/src/librustc_back/target/i686_unknown_freebsd.rs +++ b/src/librustc_target/spec/i686_unknown_freebsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); diff --git a/src/librustc_back/target/i686_unknown_haiku.rs b/src/librustc_target/spec/i686_unknown_haiku.rs similarity index 95% rename from src/librustc_back/target/i686_unknown_haiku.rs rename to src/librustc_target/spec/i686_unknown_haiku.rs index 02a15d6445c47..98f0787bebaf8 100644 --- a/src/librustc_back/target/i686_unknown_haiku.rs +++ b/src/librustc_target/spec/i686_unknown_haiku.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::haiku_base::opts(); diff --git a/src/librustc_back/target/i686_unknown_linux_gnu.rs b/src/librustc_target/spec/i686_unknown_linux_gnu.rs similarity index 95% rename from src/librustc_back/target/i686_unknown_linux_gnu.rs rename to src/librustc_target/spec/i686_unknown_linux_gnu.rs index b509e019c7e1a..c3ff347882da1 100644 --- a/src/librustc_back/target/i686_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/i686_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/i686_unknown_linux_musl.rs b/src/librustc_target/spec/i686_unknown_linux_musl.rs similarity index 97% rename from src/librustc_back/target/i686_unknown_linux_musl.rs rename to src/librustc_target/spec/i686_unknown_linux_musl.rs index 99c0d4c817915..c02076c071a1d 100644 --- a/src/librustc_back/target/i686_unknown_linux_musl.rs +++ b/src/librustc_target/spec/i686_unknown_linux_musl.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_back/target/i686_unknown_netbsd.rs b/src/librustc_target/spec/i686_unknown_netbsd.rs similarity index 95% rename from src/librustc_back/target/i686_unknown_netbsd.rs rename to src/librustc_target/spec/i686_unknown_netbsd.rs index dd21c205106ea..d60ed9885991d 100644 --- a/src/librustc_back/target/i686_unknown_netbsd.rs +++ b/src/librustc_target/spec/i686_unknown_netbsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_back/target/i686_unknown_openbsd.rs b/src/librustc_target/spec/i686_unknown_openbsd.rs similarity index 95% rename from src/librustc_back/target/i686_unknown_openbsd.rs rename to src/librustc_target/spec/i686_unknown_openbsd.rs index 8daa5fcb88b3f..79c059c8f952d 100644 --- a/src/librustc_back/target/i686_unknown_openbsd.rs +++ b/src/librustc_target/spec/i686_unknown_openbsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::openbsd_base::opts(); diff --git a/src/librustc_back/target/l4re_base.rs b/src/librustc_target/spec/l4re_base.rs similarity index 95% rename from src/librustc_back/target/l4re_base.rs rename to src/librustc_target/spec/l4re_base.rs index 3b13ef0150064..4ebc930d48b6f 100644 --- a/src/librustc_back/target/l4re_base.rs +++ b/src/librustc_target/spec/l4re_base.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use PanicStrategy; -use target::{LinkArgs, TargetOptions}; +use spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions}; use std::default::Default; //use std::process::Command; diff --git a/src/librustc_back/target/linux_base.rs b/src/librustc_target/spec/linux_base.rs similarity index 95% rename from src/librustc_back/target/linux_base.rs rename to src/librustc_target/spec/linux_base.rs index 52f700ac7519f..4a9cd9e2f3233 100644 --- a/src/librustc_back/target/linux_base.rs +++ b/src/librustc_target/spec/linux_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions, RelroLevel}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/linux_musl_base.rs b/src/librustc_target/spec/linux_musl_base.rs similarity index 98% rename from src/librustc_back/target/linux_musl_base.rs rename to src/librustc_target/spec/linux_musl_base.rs index 6e5e139715ccc..293f23eab3883 100644 --- a/src/librustc_back/target/linux_musl_base.rs +++ b/src/librustc_target/spec/linux_musl_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::TargetOptions; +use spec::{LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs similarity index 95% rename from src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs rename to src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs index 5c3cf31b3e45f..1f60d918908d0 100644 --- a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs +++ b/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs similarity index 95% rename from src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs rename to src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs index 96988388e811e..e42fde8d403fb 100644 --- a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs +++ b/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/mips_unknown_linux_gnu.rs b/src/librustc_target/spec/mips_unknown_linux_gnu.rs similarity index 94% rename from src/librustc_back/target/mips_unknown_linux_gnu.rs rename to src/librustc_target/spec/mips_unknown_linux_gnu.rs index cffd1daed99f2..59e15137cf40d 100644 --- a/src/librustc_back/target/mips_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/mips_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/mips_unknown_linux_musl.rs b/src/librustc_target/spec/mips_unknown_linux_musl.rs similarity index 96% rename from src/librustc_back/target/mips_unknown_linux_musl.rs rename to src/librustc_target/spec/mips_unknown_linux_musl.rs index 80168d4af4b1b..8ee399ba56c32 100644 --- a/src/librustc_back/target/mips_unknown_linux_musl.rs +++ b/src/librustc_target/spec/mips_unknown_linux_musl.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_back/target/mips_unknown_linux_uclibc.rs b/src/librustc_target/spec/mips_unknown_linux_uclibc.rs similarity index 94% rename from src/librustc_back/target/mips_unknown_linux_uclibc.rs rename to src/librustc_target/spec/mips_unknown_linux_uclibc.rs index c851cab069a1c..384ab1e413123 100644 --- a/src/librustc_back/target/mips_unknown_linux_uclibc.rs +++ b/src/librustc_target/spec/mips_unknown_linux_uclibc.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs similarity index 94% rename from src/librustc_back/target/mipsel_unknown_linux_gnu.rs rename to src/librustc_target/spec/mipsel_unknown_linux_gnu.rs index 555855b8f815d..edd29164caca8 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/mipsel_unknown_linux_musl.rs b/src/librustc_target/spec/mipsel_unknown_linux_musl.rs similarity index 96% rename from src/librustc_back/target/mipsel_unknown_linux_musl.rs rename to src/librustc_target/spec/mipsel_unknown_linux_musl.rs index 6bef2fe2ea717..1d9378ca1b814 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_musl.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_musl.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs b/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs similarity index 94% rename from src/librustc_back/target/mipsel_unknown_linux_uclibc.rs rename to src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs index a5dbdd1118359..a1db1791bb7ce 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/mod.rs b/src/librustc_target/spec/mod.rs similarity index 93% rename from src/librustc_back/target/mod.rs rename to src/librustc_target/spec/mod.rs index e46266b576e24..1e94f03788586 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -49,10 +49,10 @@ use std::collections::BTreeMap; use std::default::Default; use std::{fmt, io}; use std::path::{Path, PathBuf}; -use syntax::abi::{Abi, lookup as lookup_abi}; - -use {LinkerFlavor, PanicStrategy, RelroLevel}; +use std::str::FromStr; +use spec::abi::{Abi, lookup as lookup_abi}; +pub mod abi; mod android_base; mod apple_base; mod apple_ios_base; @@ -74,6 +74,133 @@ mod l4re_base; mod fuchsia_base; mod redox_base; +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, + RustcEncodable, RustcDecodable)] +pub enum LinkerFlavor { + Em, + Gcc, + Ld, + Msvc, + Lld(LldFlavor), +} + +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, + RustcEncodable, RustcDecodable)] +pub enum LldFlavor { + Wasm, + Ld64, + Ld, + Link, +} + +impl ToJson for LinkerFlavor { + fn to_json(&self) -> Json { + self.desc().to_json() + } +} +macro_rules! flavor_mappings { + ($((($($flavor:tt)*), $string:expr),)*) => ( + impl LinkerFlavor { + pub const fn one_of() -> &'static str { + concat!("one of: ", $($string, " ",)+) + } + + pub fn from_str(s: &str) -> Option { + Some(match s { + $($string => $($flavor)*,)+ + _ => return None, + }) + } + + pub fn desc(&self) -> &str { + match *self { + $($($flavor)* => $string,)+ + } + } + } + ) +} + + +flavor_mappings! { + ((LinkerFlavor::Em), "em"), + ((LinkerFlavor::Gcc), "gcc"), + ((LinkerFlavor::Ld), "ld"), + ((LinkerFlavor::Msvc), "msvc"), + ((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"), + ((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"), + ((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"), + ((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"), +} + +#[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(), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] +pub enum RelroLevel { + Full, + Partial, + Off, + None, +} + +impl RelroLevel { + pub fn desc(&self) -> &str { + match *self { + RelroLevel::Full => "full", + RelroLevel::Partial => "partial", + RelroLevel::Off => "off", + RelroLevel::None => "none", + } + } +} + +impl FromStr for RelroLevel { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "full" => Ok(RelroLevel::Full), + "partial" => Ok(RelroLevel::Partial), + "off" => Ok(RelroLevel::Off), + "none" => Ok(RelroLevel::None), + _ => Err(()), + } + } +} + +impl ToJson for RelroLevel { + fn to_json(&self) -> Json { + match *self { + RelroLevel::Full => "full".to_json(), + RelroLevel::Partial => "partial".to_json(), + RelroLevel::Off => "off".to_json(), + RelroLevel::None => "None".to_json(), + } + } +} + pub type LinkArgs = BTreeMap>; pub type TargetResult = Result; @@ -271,6 +398,16 @@ pub struct Target { pub options: TargetOptions, } +pub trait HasTargetSpec: Copy { + fn target_spec(&self) -> &Target; +} + +impl<'a> HasTargetSpec for &'a Target { + fn target_spec(&self) -> &Target { + self + } +} + /// Optional aspects of a target specification. /// /// This has an implementation of `Default`, see each field for what the default is. In general, diff --git a/src/librustc_back/target/msp430_none_elf.rs b/src/librustc_target/spec/msp430_none_elf.rs similarity index 97% rename from src/librustc_back/target/msp430_none_elf.rs rename to src/librustc_target/spec/msp430_none_elf.rs index 31df9be0bc3f8..ce42a908b0e43 100644 --- a/src/librustc_back/target/msp430_none_elf.rs +++ b/src/librustc_target/spec/msp430_none_elf.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use {LinkerFlavor, PanicStrategy}; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/netbsd_base.rs b/src/librustc_target/spec/netbsd_base.rs similarity index 95% rename from src/librustc_back/target/netbsd_base.rs rename to src/librustc_target/spec/netbsd_base.rs index 1cb311371938e..8b6bb5dec9138 100644 --- a/src/librustc_back/target/netbsd_base.rs +++ b/src/librustc_target/spec/netbsd_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions, RelroLevel}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/openbsd_base.rs b/src/librustc_target/spec/openbsd_base.rs similarity index 95% rename from src/librustc_back/target/openbsd_base.rs rename to src/librustc_target/spec/openbsd_base.rs index 311e260ee3f34..90ab1135c54b0 100644 --- a/src/librustc_back/target/openbsd_base.rs +++ b/src/librustc_target/spec/openbsd_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions, RelroLevel}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs similarity index 95% rename from src/librustc_back/target/powerpc64_unknown_linux_gnu.rs rename to src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs index 1f119c7204b16..1959871161343 100644 --- a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult, RelroLevel}; +use spec::{LinkerFlavor, Target, TargetResult, RelroLevel}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs similarity index 95% rename from src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs rename to src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs index 13c59785d480b..39840692dff18 100644 --- a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs similarity index 95% rename from src/librustc_back/target/powerpc_unknown_linux_gnu.rs rename to src/librustc_target/spec/powerpc_unknown_linux_gnu.rs index 1797126b3104a..c05b110a75d39 100644 --- a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/powerpc_unknown_linux_gnuspe.rs b/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs similarity index 95% rename from src/librustc_back/target/powerpc_unknown_linux_gnuspe.rs rename to src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs index ffcc321749b5a..c76c3119c87c5 100644 --- a/src/librustc_back/target/powerpc_unknown_linux_gnuspe.rs +++ b/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/powerpc_unknown_netbsd.rs b/src/librustc_target/spec/powerpc_unknown_netbsd.rs similarity index 95% rename from src/librustc_back/target/powerpc_unknown_netbsd.rs rename to src/librustc_target/spec/powerpc_unknown_netbsd.rs index 2c78dbd206171..c05e40b9c25d7 100644 --- a/src/librustc_back/target/powerpc_unknown_netbsd.rs +++ b/src/librustc_target/spec/powerpc_unknown_netbsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_back/target/redox_base.rs b/src/librustc_target/spec/redox_base.rs similarity index 96% rename from src/librustc_back/target/redox_base.rs rename to src/librustc_target/spec/redox_base.rs index c7915d4de72fe..c28746a936359 100644 --- a/src/librustc_back/target/redox_base.rs +++ b/src/librustc_target/spec/redox_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/s390x_unknown_linux_gnu.rs b/src/librustc_target/spec/s390x_unknown_linux_gnu.rs similarity index 96% rename from src/librustc_back/target/s390x_unknown_linux_gnu.rs rename to src/librustc_target/spec/s390x_unknown_linux_gnu.rs index d96379547fb0f..c9a9625ebab95 100644 --- a/src/librustc_back/target/s390x_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/s390x_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/solaris_base.rs b/src/librustc_target/spec/solaris_base.rs similarity index 96% rename from src/librustc_back/target/solaris_base.rs rename to src/librustc_target/spec/solaris_base.rs index 41323c9c26ba7..c14cc3f5bc3be 100644 --- a/src/librustc_back/target/solaris_base.rs +++ b/src/librustc_target/spec/solaris_base.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use spec::TargetOptions; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/sparc64_unknown_linux_gnu.rs b/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs similarity index 95% rename from src/librustc_back/target/sparc64_unknown_linux_gnu.rs rename to src/librustc_target/spec/sparc64_unknown_linux_gnu.rs index aed40e9df436e..f68b5fd24bf75 100644 --- a/src/librustc_back/target/sparc64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/sparc64_unknown_netbsd.rs b/src/librustc_target/spec/sparc64_unknown_netbsd.rs similarity index 95% rename from src/librustc_back/target/sparc64_unknown_netbsd.rs rename to src/librustc_target/spec/sparc64_unknown_netbsd.rs index 483c87909455d..1c1bca9b2b879 100644 --- a/src/librustc_back/target/sparc64_unknown_netbsd.rs +++ b/src/librustc_target/spec/sparc64_unknown_netbsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_back/target/sparc_unknown_linux_gnu.rs b/src/librustc_target/spec/sparc_unknown_linux_gnu.rs similarity index 95% rename from src/librustc_back/target/sparc_unknown_linux_gnu.rs rename to src/librustc_target/spec/sparc_unknown_linux_gnu.rs index a03e6937b2ca7..4e352374f90b0 100644 --- a/src/librustc_back/target/sparc_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/sparc_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/sparcv9_sun_solaris.rs b/src/librustc_target/spec/sparcv9_sun_solaris.rs similarity index 96% rename from src/librustc_back/target/sparcv9_sun_solaris.rs rename to src/librustc_target/spec/sparcv9_sun_solaris.rs index 1d9027275db82..7dea1b75a3c58 100644 --- a/src/librustc_back/target/sparcv9_sun_solaris.rs +++ b/src/librustc_target/spec/sparcv9_sun_solaris.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::solaris_base::opts(); diff --git a/src/librustc_back/target/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs similarity index 98% rename from src/librustc_back/target/thumb_base.rs rename to src/librustc_target/spec/thumb_base.rs index bb1fbfad2618f..fdaf1dc6110b5 100644 --- a/src/librustc_back/target/thumb_base.rs +++ b/src/librustc_target/spec/thumb_base.rs @@ -35,9 +35,8 @@ // differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of // build scripts / gcc flags. -use PanicStrategy; use std::default::Default; -use target::TargetOptions; +use spec::{PanicStrategy, TargetOptions}; pub fn opts() -> TargetOptions { // See rust-lang/rfcs#1645 for a discussion about these defaults diff --git a/src/librustc_back/target/thumbv6m_none_eabi.rs b/src/librustc_target/spec/thumbv6m_none_eabi.rs similarity index 95% rename from src/librustc_back/target/thumbv6m_none_eabi.rs rename to src/librustc_target/spec/thumbv6m_none_eabi.rs index d164fbf9d96f9..9fea07c36f4ef 100644 --- a/src/librustc_back/target/thumbv6m_none_eabi.rs +++ b/src/librustc_target/spec/thumbv6m_none_eabi.rs @@ -10,8 +10,7 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/thumbv7em_none_eabi.rs b/src/librustc_target/spec/thumbv7em_none_eabi.rs similarity index 96% rename from src/librustc_back/target/thumbv7em_none_eabi.rs rename to src/librustc_target/spec/thumbv7em_none_eabi.rs index 7e66ddf7b06a7..ab85c97b1b5ba 100644 --- a/src/librustc_back/target/thumbv7em_none_eabi.rs +++ b/src/librustc_target/spec/thumbv7em_none_eabi.rs @@ -19,8 +19,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/thumbv7em_none_eabihf.rs b/src/librustc_target/spec/thumbv7em_none_eabihf.rs similarity index 97% rename from src/librustc_back/target/thumbv7em_none_eabihf.rs rename to src/librustc_target/spec/thumbv7em_none_eabihf.rs index 31835de36d6a4..4e62f29134edf 100644 --- a/src/librustc_back/target/thumbv7em_none_eabihf.rs +++ b/src/librustc_target/spec/thumbv7em_none_eabihf.rs @@ -18,8 +18,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=-fp-only-sp` flag. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/thumbv7m_none_eabi.rs b/src/librustc_target/spec/thumbv7m_none_eabi.rs similarity index 94% rename from src/librustc_back/target/thumbv7m_none_eabi.rs rename to src/librustc_target/spec/thumbv7m_none_eabi.rs index 8f16ae4ea12df..10dc503388afe 100644 --- a/src/librustc_back/target/thumbv7m_none_eabi.rs +++ b/src/librustc_target/spec/thumbv7m_none_eabi.rs @@ -10,8 +10,7 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_back/target/wasm32_experimental_emscripten.rs b/src/librustc_target/spec/wasm32_experimental_emscripten.rs similarity index 97% rename from src/librustc_back/target/wasm32_experimental_emscripten.rs rename to src/librustc_target/spec/wasm32_experimental_emscripten.rs index 13dee3a576869..164df20f84f34 100644 --- a/src/librustc_back/target/wasm32_experimental_emscripten.rs +++ b/src/librustc_target/spec/wasm32_experimental_emscripten.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use super::{LinkArgs, Target, TargetOptions}; +use super::{LinkArgs, LinkerFlavor, Target, TargetOptions}; pub fn target() -> Result { let mut post_link_args = LinkArgs::new(); diff --git a/src/librustc_back/target/wasm32_unknown_emscripten.rs b/src/librustc_target/spec/wasm32_unknown_emscripten.rs similarity index 96% rename from src/librustc_back/target/wasm32_unknown_emscripten.rs rename to src/librustc_target/spec/wasm32_unknown_emscripten.rs index 2770e67e30a5b..5077abf1e0eb3 100644 --- a/src/librustc_back/target/wasm32_unknown_emscripten.rs +++ b/src/librustc_target/spec/wasm32_unknown_emscripten.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use super::{LinkArgs, Target, TargetOptions}; +use super::{LinkArgs, LinkerFlavor, Target, TargetOptions}; pub fn target() -> Result { let mut post_link_args = LinkArgs::new(); diff --git a/src/librustc_back/target/wasm32_unknown_unknown.rs b/src/librustc_target/spec/wasm32_unknown_unknown.rs similarity index 97% rename from src/librustc_back/target/wasm32_unknown_unknown.rs rename to src/librustc_target/spec/wasm32_unknown_unknown.rs index 1d84e13751740..56170bbb869f3 100644 --- a/src/librustc_back/target/wasm32_unknown_unknown.rs +++ b/src/librustc_target/spec/wasm32_unknown_unknown.rs @@ -17,8 +17,7 @@ // (aka panic=abort by default), but otherwise this is in general a relatively // standard target. -use {LinkerFlavor, LldFlavor}; -use super::{Target, TargetOptions, PanicStrategy}; +use super::{LldFlavor, LinkerFlavor, Target, TargetOptions, PanicStrategy}; pub fn target() -> Result { let opts = TargetOptions { diff --git a/src/librustc_back/target/windows_base.rs b/src/librustc_target/spec/windows_base.rs similarity index 98% rename from src/librustc_back/target/windows_base.rs rename to src/librustc_target/spec/windows_base.rs index 4b4fb27caa839..176df9f13253d 100644 --- a/src/librustc_back/target/windows_base.rs +++ b/src/librustc_target/spec/windows_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs similarity index 96% rename from src/librustc_back/target/windows_msvc_base.rs rename to src/librustc_target/spec/windows_msvc_base.rs index fee5a0284c806..1f00e690cd352 100644 --- a/src/librustc_back/target/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{LinkArgs, TargetOptions}; +use spec::{LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_back/target/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs similarity index 96% rename from src/librustc_back/target/x86_64_apple_darwin.rs rename to src/librustc_target/spec/x86_64_apple_darwin.rs index 71ac360eb9906..a4efd7e0066ff 100644 --- a/src/librustc_back/target/x86_64_apple_darwin.rs +++ b/src/librustc_target/spec/x86_64_apple_darwin.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::apple_base::opts(); diff --git a/src/librustc_back/target/x86_64_apple_ios.rs b/src/librustc_target/spec/x86_64_apple_ios.rs similarity index 94% rename from src/librustc_back/target/x86_64_apple_ios.rs rename to src/librustc_target/spec/x86_64_apple_ios.rs index eed99e3784ce0..eeb53d72fe8a3 100644 --- a/src/librustc_back/target/x86_64_apple_ios.rs +++ b/src/librustc_target/spec/x86_64_apple_ios.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetOptions, TargetResult}; +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_back/target/x86_64_linux_android.rs b/src/librustc_target/spec/x86_64_linux_android.rs similarity index 96% rename from src/librustc_back/target/x86_64_linux_android.rs rename to src/librustc_target/spec/x86_64_linux_android.rs index 2aae73941539f..06abe916784dc 100644 --- a/src/librustc_back/target/x86_64_linux_android.rs +++ b/src/librustc_target/spec/x86_64_linux_android.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::android_base::opts(); diff --git a/src/librustc_back/target/x86_64_pc_windows_gnu.rs b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs similarity index 95% rename from src/librustc_back/target/x86_64_pc_windows_gnu.rs rename to src/librustc_target/spec/x86_64_pc_windows_gnu.rs index 70062d1363841..8d2f702bc4a0f 100644 --- a/src/librustc_back/target/x86_64_pc_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_base::opts(); diff --git a/src/librustc_back/target/x86_64_pc_windows_msvc.rs b/src/librustc_target/spec/x86_64_pc_windows_msvc.rs similarity index 95% rename from src/librustc_back/target/x86_64_pc_windows_msvc.rs rename to src/librustc_target/spec/x86_64_pc_windows_msvc.rs index 813d0f1bad947..ab610ea94ae89 100644 --- a/src/librustc_back/target/x86_64_pc_windows_msvc.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_msvc.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); diff --git a/src/librustc_back/target/x86_64_rumprun_netbsd.rs b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs similarity index 96% rename from src/librustc_back/target/x86_64_rumprun_netbsd.rs rename to src/librustc_target/spec/x86_64_rumprun_netbsd.rs index 3158665a2e28d..ed15cfd9036f5 100644 --- a/src/librustc_back/target/x86_64_rumprun_netbsd.rs +++ b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_back/target/x86_64_sun_solaris.rs b/src/librustc_target/spec/x86_64_sun_solaris.rs similarity index 95% rename from src/librustc_back/target/x86_64_sun_solaris.rs rename to src/librustc_target/spec/x86_64_sun_solaris.rs index d554138539083..e84f21c500664 100644 --- a/src/librustc_back/target/x86_64_sun_solaris.rs +++ b/src/librustc_target/spec/x86_64_sun_solaris.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::solaris_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_bitrig.rs b/src/librustc_target/spec/x86_64_unknown_bitrig.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_bitrig.rs rename to src/librustc_target/spec/x86_64_unknown_bitrig.rs index 1ea985d70eaca..21ec6dffcbbce 100644 --- a/src/librustc_back/target/x86_64_unknown_bitrig.rs +++ b/src/librustc_target/spec/x86_64_unknown_bitrig.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::bitrig_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_cloudabi.rs b/src/librustc_target/spec/x86_64_unknown_cloudabi.rs similarity index 96% rename from src/librustc_back/target/x86_64_unknown_cloudabi.rs rename to src/librustc_target/spec/x86_64_unknown_cloudabi.rs index d1a9cb1cd7e7d..8dc8bd7a7fad9 100644 --- a/src/librustc_back/target/x86_64_unknown_cloudabi.rs +++ b/src/librustc_target/spec/x86_64_unknown_cloudabi.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_dragonfly.rs b/src/librustc_target/spec/x86_64_unknown_dragonfly.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_dragonfly.rs rename to src/librustc_target/spec/x86_64_unknown_dragonfly.rs index 56e4685fed5b4..50b2871c2ee9c 100644 --- a/src/librustc_back/target/x86_64_unknown_dragonfly.rs +++ b/src/librustc_target/spec/x86_64_unknown_dragonfly.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::dragonfly_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_freebsd.rs b/src/librustc_target/spec/x86_64_unknown_freebsd.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_freebsd.rs rename to src/librustc_target/spec/x86_64_unknown_freebsd.rs index 3d26592530abf..f0aa81ed4598b 100644 --- a/src/librustc_back/target/x86_64_unknown_freebsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_freebsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_fuchsia.rs b/src/librustc_target/spec/x86_64_unknown_fuchsia.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_fuchsia.rs rename to src/librustc_target/spec/x86_64_unknown_fuchsia.rs index 6e97d53cfad6a..a510ec8eb3426 100644 --- a/src/librustc_back/target/x86_64_unknown_fuchsia.rs +++ b/src/librustc_target/spec/x86_64_unknown_fuchsia.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::fuchsia_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_haiku.rs b/src/librustc_target/spec/x86_64_unknown_haiku.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_haiku.rs rename to src/librustc_target/spec/x86_64_unknown_haiku.rs index f42c480e7a117..1e78461861a95 100644 --- a/src/librustc_back/target/x86_64_unknown_haiku.rs +++ b/src/librustc_target/spec/x86_64_unknown_haiku.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::haiku_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs b/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs rename to src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs index 821a77f52f511..f1179c18294d3 100644 --- a/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs +++ b/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::l4re_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_linux_gnu.rs b/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_linux_gnu.rs rename to src/librustc_target/spec/x86_64_unknown_linux_gnu.rs index cfe80c96732bf..56559661b03cb 100644 --- a/src/librustc_back/target/x86_64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_linux_gnux32.rs b/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs similarity index 96% rename from src/librustc_back/target/x86_64_unknown_linux_gnux32.rs rename to src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs index 7038203283643..72b5bd27c7dfe 100644 --- a/src/librustc_back/target/x86_64_unknown_linux_gnux32.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_linux_musl.rs b/src/librustc_target/spec/x86_64_unknown_linux_musl.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_linux_musl.rs rename to src/librustc_target/spec/x86_64_unknown_linux_musl.rs index 7e304748e3207..f1924efcf98b5 100644 --- a/src/librustc_back/target/x86_64_unknown_linux_musl.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_musl.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_netbsd.rs b/src/librustc_target/spec/x86_64_unknown_netbsd.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_netbsd.rs rename to src/librustc_target/spec/x86_64_unknown_netbsd.rs index 7afb446f5dc97..6e8ca6b9e1991 100644 --- a/src/librustc_back/target/x86_64_unknown_netbsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_netbsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_openbsd.rs b/src/librustc_target/spec/x86_64_unknown_openbsd.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_openbsd.rs rename to src/librustc_target/spec/x86_64_unknown_openbsd.rs index e4bbdbec4c850..c60b7c86680f8 100644 --- a/src/librustc_back/target/x86_64_unknown_openbsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_openbsd.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::openbsd_base::opts(); diff --git a/src/librustc_back/target/x86_64_unknown_redox.rs b/src/librustc_target/spec/x86_64_unknown_redox.rs similarity index 95% rename from src/librustc_back/target/x86_64_unknown_redox.rs rename to src/librustc_target/spec/x86_64_unknown_redox.rs index 401fa4ca2cbdd..548dfb06109ff 100644 --- a/src/librustc_back/target/x86_64_unknown_redox.rs +++ b/src/librustc_target/spec/x86_64_unknown_redox.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use LinkerFlavor; -use target::{Target, TargetResult}; +use spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::redox_base::opts(); diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 176fd86f29ddc..32432d6cc835d 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -10,7 +10,6 @@ crate-type = ["dylib"] test = false [dependencies] -bitflags = "1.0" cc = "1.0.1" flate2 = "1.0" jobserver = "0.1.5" @@ -21,7 +20,7 @@ rustc = { path = "../librustc" } rustc-demangle = "0.1.4" rustc_allocator = { path = "../librustc_allocator" } rustc_apfloat = { path = "../librustc_apfloat" } -rustc_back = { path = "../librustc_back" } +rustc_target = { path = "../librustc_target" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } @@ -40,9 +39,9 @@ tempdir = "0.3" env_logger = { version = "0.5", default-features = false } [features] -# Used to communicate the feature to `rustc_back` in the same manner that the +# Used to communicate the feature to `rustc_target` in the same manner that the # `rustc` driver script communicate this. -jemalloc = ["rustc_back/jemalloc"] +jemalloc = ["rustc_target/jemalloc"] # This is used to convince Cargo to separately cache builds of `rustc_trans` # when this option is enabled or not. That way we can build two, cache two diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 19ae1fa0478ea..483f36afe27d6 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -13,77 +13,20 @@ use base; use builder::Builder; use common::{ty_fn_sig, C_usize}; use context::CodegenCx; -use cabi_x86; -use cabi_x86_64; -use cabi_x86_win64; -use cabi_arm; -use cabi_aarch64; -use cabi_powerpc; -use cabi_powerpc64; -use cabi_s390x; -use cabi_mips; -use cabi_mips64; -use cabi_asmjs; -use cabi_msp430; -use cabi_sparc; -use cabi_sparc64; -use cabi_nvptx; -use cabi_nvptx64; -use cabi_hexagon; -use cabi_wasm32; use mir::place::PlaceRef; use mir::operand::OperandValue; use type_::Type; use type_of::{LayoutLlvmExt, PointerKind}; +use rustc_target::abi::{LayoutOf, Size, TyLayout}; use rustc::ty::{self, Ty}; -use rustc::ty::layout::{self, Align, Size, TyLayout}; -use rustc::ty::layout::{HasDataLayout, LayoutOf}; +use rustc::ty::layout; use libc::c_uint; -use std::cmp; -pub use syntax::abi::Abi; +pub use rustc_target::spec::abi::Abi; pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum PassMode { - /// Ignore the argument (useful for empty struct). - Ignore, - /// Pass the argument directly. - Direct(ArgAttributes), - /// Pass a pair's elements directly in two arguments. - Pair(ArgAttributes, ArgAttributes), - /// Pass the argument after casting it, to either - /// a single uniform or a pair of registers. - Cast(CastTarget), - /// Pass the argument indirectly via a hidden pointer. - Indirect(ArgAttributes), -} - -// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest -// of this module -pub use self::attr_impl::ArgAttribute; - -#[allow(non_upper_case_globals)] -#[allow(unused)] -mod attr_impl { - // The subset of llvm::Attribute needed for arguments, packed into a bitfield. - bitflags! { - #[derive(Default)] - pub struct ArgAttribute: u16 { - const ByVal = 1 << 0; - const NoAlias = 1 << 1; - const NoCapture = 1 << 2; - const NonNull = 1 << 3; - const ReadOnly = 1 << 4; - const SExt = 1 << 5; - const StructRet = 1 << 6; - const ZExt = 1 << 7; - const InReg = 1 << 8; - } - } -} +pub use rustc_target::abi::call::*; macro_rules! for_each_kind { ($flags: ident, $f: ident, $($kind: ident),+) => ({ @@ -91,41 +34,24 @@ macro_rules! for_each_kind { }) } -impl ArgAttribute { +trait ArgAttributeExt { + fn for_each_kind(&self, f: F) where F: FnMut(llvm::Attribute); +} + +impl ArgAttributeExt for ArgAttribute { fn for_each_kind(&self, mut f: F) where F: FnMut(llvm::Attribute) { for_each_kind!(self, f, ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg) } } -/// A compact representation of LLVM attributes (at least those relevant for this module) -/// that can be manipulated without interacting with LLVM's Attribute machinery. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct ArgAttributes { - regular: ArgAttribute, - pointee_size: Size, - pointee_align: Option +pub trait ArgAttributesExt { + fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef); + fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef); } -impl ArgAttributes { - fn new() -> Self { - ArgAttributes { - regular: ArgAttribute::default(), - pointee_size: Size::from_bytes(0), - pointee_align: None, - } - } - - pub fn set(&mut self, attr: ArgAttribute) -> &mut Self { - self.regular = self.regular | attr; - self - } - - pub fn contains(&self, attr: ArgAttribute) -> bool { - self.regular.contains(attr) - } - - pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { +impl ArgAttributesExt for ArgAttributes { + fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { let mut regular = self.regular; unsafe { let deref = self.pointee_size.bytes(); @@ -150,7 +76,7 @@ impl ArgAttributes { } } - pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) { + fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) { let mut regular = self.regular; unsafe { let deref = self.pointee_size.bytes(); @@ -175,67 +101,13 @@ impl ArgAttributes { } } } -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum RegKind { - Integer, - Float, - Vector -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct Reg { - pub kind: RegKind, - pub size: Size, -} - -macro_rules! reg_ctor { - ($name:ident, $kind:ident, $bits:expr) => { - pub fn $name() -> Reg { - Reg { - kind: RegKind::$kind, - size: Size::from_bits($bits) - } - } - } -} - -impl Reg { - reg_ctor!(i8, Integer, 8); - reg_ctor!(i16, Integer, 16); - reg_ctor!(i32, Integer, 32); - reg_ctor!(i64, Integer, 64); - reg_ctor!(f32, Float, 32); - reg_ctor!(f64, Float, 64); +pub trait LlvmType { + fn llvm_type(&self, cx: &CodegenCx) -> Type; } -impl Reg { - pub fn align(&self, cx: &CodegenCx) -> Align { - let dl = cx.data_layout(); - match self.kind { - RegKind::Integer => { - match self.size.bits() { - 1 => dl.i1_align, - 2...8 => dl.i8_align, - 9...16 => dl.i16_align, - 17...32 => dl.i32_align, - 33...64 => dl.i64_align, - 65...128 => dl.i128_align, - _ => bug!("unsupported integer: {:?}", self) - } - } - RegKind::Float => { - match self.size.bits() { - 32 => dl.f32_align, - 64 => dl.f64_align, - _ => bug!("unsupported float: {:?}", self) - } - } - RegKind::Vector => dl.vector_align(self.size) - } - } - - pub fn llvm_type(&self, cx: &CodegenCx) -> Type { +impl LlvmType for Reg { + fn llvm_type(&self, cx: &CodegenCx) -> Type { match self.kind { RegKind::Integer => Type::ix(cx, self.size.bits()), RegKind::Float => { @@ -252,180 +124,8 @@ impl Reg { } } -/// An argument passed entirely registers with the -/// same kind (e.g. HFA / HVA on PPC64 and AArch64). -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct Uniform { - pub unit: Reg, - - /// The total size of the argument, which can be: - /// * equal to `unit.size` (one scalar/vector) - /// * a multiple of `unit.size` (an array of scalar/vectors) - /// * if `unit.kind` is `Integer`, the last element - /// can be shorter, i.e. `{ i64, i64, i32 }` for - /// 64-bit integers with a total size of 20 bytes - pub total: Size, -} - -impl From for Uniform { - fn from(unit: Reg) -> Uniform { - Uniform { - unit, - total: unit.size - } - } -} - -impl Uniform { - pub fn align(&self, cx: &CodegenCx) -> Align { - self.unit.align(cx) - } -} - -pub trait LayoutExt<'tcx> { - fn is_aggregate(&self) -> bool; - fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option; -} - -impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> { - fn is_aggregate(&self) -> bool { - match self.abi { - layout::Abi::Uninhabited | - layout::Abi::Scalar(_) | - layout::Abi::Vector { .. } => false, - layout::Abi::ScalarPair(..) | - layout::Abi::Aggregate { .. } => true - } - } - - fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option { - match self.abi { - layout::Abi::Uninhabited => None, - - // The primitive for this algorithm. - layout::Abi::Scalar(ref scalar) => { - let kind = match scalar.value { - layout::Int(..) | - layout::Pointer => RegKind::Integer, - layout::F32 | - layout::F64 => RegKind::Float - }; - Some(Reg { - kind, - size: self.size - }) - } - - layout::Abi::Vector { .. } => { - Some(Reg { - kind: RegKind::Vector, - size: self.size - }) - } - - layout::Abi::ScalarPair(..) | - layout::Abi::Aggregate { .. } => { - let mut total = Size::from_bytes(0); - let mut result = None; - - let is_union = match self.fields { - layout::FieldPlacement::Array { count, .. } => { - if count > 0 { - return self.field(cx, 0).homogeneous_aggregate(cx); - } else { - return None; - } - } - layout::FieldPlacement::Union(_) => true, - layout::FieldPlacement::Arbitrary { .. } => false - }; - - for i in 0..self.fields.count() { - if !is_union && total != self.fields.offset(i) { - return None; - } - - let field = self.field(cx, i); - match (result, field.homogeneous_aggregate(cx)) { - // The field itself must be a homogeneous aggregate. - (_, None) => return None, - // If this is the first field, record the unit. - (None, Some(unit)) => { - result = Some(unit); - } - // For all following fields, the unit must be the same. - (Some(prev_unit), Some(unit)) => { - if prev_unit != unit { - return None; - } - } - } - - // Keep track of the offset (without padding). - let size = field.size; - if is_union { - total = cmp::max(total, size); - } else { - total += size; - } - } - - // There needs to be no padding. - if total != self.size { - None - } else { - result - } - } - } - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct CastTarget { - pub prefix: [Option; 8], - pub prefix_chunk: Size, - pub rest: Uniform, -} - -impl From for CastTarget { - fn from(unit: Reg) -> CastTarget { - CastTarget::from(Uniform::from(unit)) - } -} - -impl From for CastTarget { - fn from(uniform: Uniform) -> CastTarget { - CastTarget { - prefix: [None; 8], - prefix_chunk: Size::from_bytes(0), - rest: uniform - } - } -} - -impl CastTarget { - pub fn pair(a: Reg, b: Reg) -> CastTarget { - CastTarget { - prefix: [Some(a.kind), None, None, None, None, None, None, None], - prefix_chunk: a.size, - rest: Uniform::from(b) - } - } - - pub fn size(&self, cx: &CodegenCx) -> Size { - (self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64) - .abi_align(self.rest.align(cx)) + self.rest.total - } - - pub fn align(&self, cx: &CodegenCx) -> Align { - self.prefix.iter() - .filter_map(|x| x.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.align(cx))) - .fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)), - |acc, align| acc.max(align)) - } - - pub fn llvm_type(&self, cx: &CodegenCx) -> Type { +impl LlvmType for CastTarget { + fn llvm_type(&self, cx: &CodegenCx) -> Type { let rest_ll_unit = self.rest.unit.llvm_type(cx); let rest_count = self.rest.total.bytes() / self.rest.unit.size.bytes(); let rem_bytes = self.rest.total.bytes() % self.rest.unit.size.bytes(); @@ -460,97 +160,16 @@ impl CastTarget { } } -/// Information about how to pass an argument to, -/// or return a value from, a function, under some ABI. -#[derive(Debug)] -pub struct ArgType<'tcx> { - pub layout: TyLayout<'tcx>, - - /// Dummy argument, which is emitted before the real argument. - pub pad: Option, - - pub mode: PassMode, +pub trait ArgTypeExt<'a, 'tcx> { + fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; + fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>); + fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>); } -impl<'a, 'tcx> ArgType<'tcx> { - fn new(layout: TyLayout<'tcx>) -> ArgType<'tcx> { - ArgType { - layout, - pad: None, - mode: PassMode::Direct(ArgAttributes::new()), - } - } - - pub fn make_indirect(&mut self) { - assert_eq!(self.mode, PassMode::Direct(ArgAttributes::new())); - - // Start with fresh attributes for the pointer. - let mut attrs = ArgAttributes::new(); - - // For non-immediate arguments the callee gets its own copy of - // the value on the stack, so there are no aliases. It's also - // program-invisible so can't possibly capture - attrs.set(ArgAttribute::NoAlias) - .set(ArgAttribute::NoCapture) - .set(ArgAttribute::NonNull); - attrs.pointee_size = self.layout.size; - // FIXME(eddyb) We should be doing this, but at least on - // i686-pc-windows-msvc, it results in wrong stack offsets. - // attrs.pointee_align = Some(self.layout.align); - - self.mode = PassMode::Indirect(attrs); - } - - pub fn make_indirect_byval(&mut self) { - self.make_indirect(); - match self.mode { - PassMode::Indirect(ref mut attrs) => { - attrs.set(ArgAttribute::ByVal); - } - _ => bug!() - } - } - - pub fn extend_integer_width_to(&mut self, bits: u64) { - // Only integers have signedness - if let layout::Abi::Scalar(ref scalar) = self.layout.abi { - if let layout::Int(i, signed) = scalar.value { - if i.size().bits() < bits { - if let PassMode::Direct(ref mut attrs) = self.mode { - attrs.set(if signed { - ArgAttribute::SExt - } else { - ArgAttribute::ZExt - }); - } - } - } - } - } - - pub fn cast_to>(&mut self, target: T) { - assert_eq!(self.mode, PassMode::Direct(ArgAttributes::new())); - self.mode = PassMode::Cast(target.into()); - } - - pub fn pad_with(&mut self, reg: Reg) { - self.pad = Some(reg); - } - - pub fn is_indirect(&self) -> bool { - match self.mode { - PassMode::Indirect(_) => true, - _ => false - } - } - - pub fn is_ignore(&self) -> bool { - self.mode == PassMode::Ignore - } - +impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { /// Get the LLVM type for a place of the original Rust type of /// this argument/return, i.e. the result of `type_of::type_of`. - pub fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { + fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { self.layout.llvm_type(cx) } @@ -558,7 +177,7 @@ impl<'a, 'tcx> ArgType<'tcx> { /// place for the original Rust type of this argument/return. /// Can be used for both storing formal arguments into Rust variables /// or results of call/invoke instructions into their destinations. - pub fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) { + fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) { if self.is_ignore() { return; } @@ -610,7 +229,7 @@ impl<'a, 'tcx> ArgType<'tcx> { } } - pub fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) { + fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) { let mut next = || { let val = llvm::get_param(bx.llfn(), *idx as c_uint); *idx += 1; @@ -628,26 +247,29 @@ impl<'a, 'tcx> ArgType<'tcx> { } } -/// Metadata describing how the arguments to a native function -/// should be passed in order to respect the native ABI. -/// -/// I will do my best to describe this structure, but these -/// comments are reverse-engineered and may be inaccurate. -NDM -#[derive(Debug)] -pub struct FnType<'tcx> { - /// The LLVM types of each argument. - pub args: Vec>, - - /// LLVM return type. - pub ret: ArgType<'tcx>, - - pub variadic: bool, - - pub cconv: llvm::CallConv +pub trait FnTypeExt<'a, 'tcx> { + fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>) + -> Self; + fn new(cx: &CodegenCx<'a, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>]) -> Self; + fn new_vtable(cx: &CodegenCx<'a, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>]) -> Self; + fn unadjusted(cx: &CodegenCx<'a, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>]) -> Self; + fn adjust_for_abi(&mut self, + cx: &CodegenCx<'a, 'tcx>, + abi: Abi); + fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; + fn llvm_cconv(&self) -> llvm::CallConv; + fn apply_attrs_llfn(&self, llfn: ValueRef); + fn apply_attrs_callsite(&self, callsite: ValueRef); } -impl<'a, 'tcx> FnType<'tcx> { - pub fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>) +impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { + fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>) -> Self { let fn_ty = instance.ty(cx.tcx); let sig = ty_fn_sig(cx, fn_ty); @@ -655,17 +277,17 @@ impl<'a, 'tcx> FnType<'tcx> { FnType::new(cx, sig, &[]) } - pub fn new(cx: &CodegenCx<'a, 'tcx>, + fn new(cx: &CodegenCx<'a, 'tcx>, sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> FnType<'tcx> { + extra_args: &[Ty<'tcx>]) -> Self { let mut fn_ty = FnType::unadjusted(cx, sig, extra_args); fn_ty.adjust_for_abi(cx, sig.abi); fn_ty } - pub fn new_vtable(cx: &CodegenCx<'a, 'tcx>, + fn new_vtable(cx: &CodegenCx<'a, 'tcx>, sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> FnType<'tcx> { + extra_args: &[Ty<'tcx>]) -> Self { let mut fn_ty = FnType::unadjusted(cx, sig, extra_args); // Don't pass the vtable, it's not an argument of the virtual fn. { @@ -688,34 +310,34 @@ impl<'a, 'tcx> FnType<'tcx> { fn_ty } - pub fn unadjusted(cx: &CodegenCx<'a, 'tcx>, + fn unadjusted(cx: &CodegenCx<'a, 'tcx>, sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> FnType<'tcx> { + extra_args: &[Ty<'tcx>]) -> Self { debug!("FnType::unadjusted({:?}, {:?})", sig, extra_args); use self::Abi::*; - let cconv = match cx.sess().target.target.adjust_abi(sig.abi) { + let conv = match cx.sess().target.target.adjust_abi(sig.abi) { RustIntrinsic | PlatformIntrinsic | - Rust | RustCall => llvm::CCallConv, + Rust | RustCall => Conv::C, // It's the ABI's job to select this, not us. System => bug!("system abi should be selected elsewhere"), - Stdcall => llvm::X86StdcallCallConv, - Fastcall => llvm::X86FastcallCallConv, - Vectorcall => llvm::X86_VectorCall, - Thiscall => llvm::X86_ThisCall, - C => llvm::CCallConv, - Unadjusted => llvm::CCallConv, - Win64 => llvm::X86_64_Win64, - SysV64 => llvm::X86_64_SysV, - Aapcs => llvm::ArmAapcsCallConv, - PtxKernel => llvm::PtxKernel, - Msp430Interrupt => llvm::Msp430Intr, - X86Interrupt => llvm::X86_Intr, + Stdcall => Conv::X86Stdcall, + Fastcall => Conv::X86Fastcall, + Vectorcall => Conv::X86VectorCall, + Thiscall => Conv::X86ThisCall, + C => Conv::C, + Unadjusted => Conv::C, + Win64 => Conv::X86_64Win64, + SysV64 => Conv::X86_64SysV, + Aapcs => Conv::ArmAapcs, + PtxKernel => Conv::PtxKernel, + Msp430Interrupt => Conv::Msp430Intr, + X86Interrupt => Conv::X86Intr, // These API constants ought to be more specific... - Cdecl => llvm::CCallConv, + Cdecl => Conv::C, }; let mut inputs = sig.inputs(); @@ -752,7 +374,7 @@ impl<'a, 'tcx> FnType<'tcx> { // Handle safe Rust thin and fat pointers. let adjust_for_rust_scalar = |attrs: &mut ArgAttributes, scalar: &layout::Scalar, - layout: TyLayout<'tcx>, + layout: TyLayout<'tcx, Ty<'tcx>>, offset: Size, is_return: bool| { // Booleans are always an i1 that needs to be zero-extended. @@ -858,7 +480,7 @@ impl<'a, 'tcx> FnType<'tcx> { arg_of(ty, false) }).collect(), variadic: sig.variadic, - cconv, + conv, } } @@ -869,7 +491,7 @@ impl<'a, 'tcx> FnType<'tcx> { if abi == Abi::Rust || abi == Abi::RustCall || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - let fixup = |arg: &mut ArgType<'tcx>| { + let fixup = |arg: &mut ArgType<'tcx, Ty<'tcx>>| { if arg.is_ignore() { return; } match arg.layout.abi { @@ -925,52 +547,12 @@ impl<'a, 'tcx> FnType<'tcx> { return; } - match &cx.sess().target.target.arch[..] { - "x86" => { - let flavor = if abi == Abi::Fastcall { - cabi_x86::Flavor::Fastcall - } else { - cabi_x86::Flavor::General - }; - cabi_x86::compute_abi_info(cx, self, flavor); - }, - "x86_64" => if abi == Abi::SysV64 { - cabi_x86_64::compute_abi_info(cx, self); - } else if abi == Abi::Win64 || cx.sess().target.target.options.is_like_windows { - cabi_x86_win64::compute_abi_info(self); - } else { - cabi_x86_64::compute_abi_info(cx, self); - }, - "aarch64" => cabi_aarch64::compute_abi_info(cx, self), - "arm" => cabi_arm::compute_abi_info(cx, self), - "mips" => cabi_mips::compute_abi_info(cx, self), - "mips64" => cabi_mips64::compute_abi_info(cx, self), - "powerpc" => cabi_powerpc::compute_abi_info(cx, self), - "powerpc64" => cabi_powerpc64::compute_abi_info(cx, self), - "s390x" => cabi_s390x::compute_abi_info(cx, self), - "asmjs" => cabi_asmjs::compute_abi_info(cx, self), - "wasm32" => { - if cx.sess().opts.target_triple.triple().contains("emscripten") { - cabi_asmjs::compute_abi_info(cx, self) - } else { - cabi_wasm32::compute_abi_info(cx, self) - } - } - "msp430" => cabi_msp430::compute_abi_info(self), - "sparc" => cabi_sparc::compute_abi_info(cx, self), - "sparc64" => cabi_sparc64::compute_abi_info(cx, self), - "nvptx" => cabi_nvptx::compute_abi_info(self), - "nvptx64" => cabi_nvptx64::compute_abi_info(self), - "hexagon" => cabi_hexagon::compute_abi_info(self), - a => cx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)) - } - - if let PassMode::Indirect(ref mut attrs) = self.ret.mode { - attrs.set(ArgAttribute::StructRet); + if let Err(msg) = self.adjust_for_cabi(cx, abi) { + cx.sess().fatal(&msg); } } - pub fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { + fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { let mut llargument_tys = Vec::new(); let llreturn_ty = match self.ret.mode { @@ -1012,7 +594,23 @@ impl<'a, 'tcx> FnType<'tcx> { } } - pub fn apply_attrs_llfn(&self, llfn: ValueRef) { + fn llvm_cconv(&self) -> llvm::CallConv { + match self.conv { + Conv::C => llvm::CCallConv, + Conv::ArmAapcs => llvm::ArmAapcsCallConv, + Conv::Msp430Intr => llvm::Msp430Intr, + Conv::PtxKernel => llvm::PtxKernel, + Conv::X86Fastcall => llvm::X86FastcallCallConv, + Conv::X86Intr => llvm::X86_Intr, + Conv::X86Stdcall => llvm::X86StdcallCallConv, + Conv::X86ThisCall => llvm::X86_ThisCall, + Conv::X86VectorCall => llvm::X86_VectorCall, + Conv::X86_64SysV => llvm::X86_64_SysV, + Conv::X86_64Win64 => llvm::X86_64_Win64, + } + } + + fn apply_attrs_llfn(&self, llfn: ValueRef) { let mut i = 0; let mut apply = |attrs: &ArgAttributes| { attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn); @@ -1042,7 +640,7 @@ impl<'a, 'tcx> FnType<'tcx> { } } - pub fn apply_attrs_callsite(&self, callsite: ValueRef) { + fn apply_attrs_callsite(&self, callsite: ValueRef) { let mut i = 0; let mut apply = |attrs: &ArgAttributes| { attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite); @@ -1071,8 +669,9 @@ impl<'a, 'tcx> FnType<'tcx> { } } - if self.cconv != llvm::CCallConv { - llvm::SetInstructionCallConv(callsite, self.cconv); + let cconv = self.llvm_cconv(); + if cconv != llvm::CCallConv { + llvm::SetInstructionCallConv(callsite, cconv); } } } diff --git a/src/librustc_trans/back/command.rs b/src/librustc_trans/back/command.rs index a5649e98baa76..9ebbdd7c3c936 100644 --- a/src/librustc_trans/back/command.rs +++ b/src/librustc_trans/back/command.rs @@ -17,7 +17,7 @@ use std::io; use std::mem; use std::process::{self, Output}; -use rustc_back::LldFlavor; +use rustc_target::spec::LldFlavor; #[derive(Clone)] pub struct Command { diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 97683840172d2..92f9a9e8ba974 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -17,7 +17,6 @@ use super::command::Command; use super::rpath::RPathConfig; use super::rpath; use metadata::METADATA_FILENAME; -use rustc_back::LinkerFlavor; use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType, PrintRequest}; use rustc::session::config::{RUST_CGU_EXT, Lto}; use rustc::session::filesearch; @@ -30,8 +29,7 @@ use rustc::util::common::time; use rustc::util::fs::fix_windows_verbatim_for_gcc; use rustc::hir::def_id::CrateNum; use tempdir::TempDir; -use rustc_back::{PanicStrategy, RelroLevel}; -use rustc_back::target::TargetTriple; +use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor, TargetTriple}; use rustc_data_structures::fx::FxHashSet; use context::get_reloc_model; use llvm; diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index e001e809ee5f0..f9a8473464db7 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -23,7 +23,7 @@ use rustc::middle::dependency_format::Linkage; use rustc::session::Session; use rustc::session::config::{self, CrateType, OptLevel, DebugInfoLevel}; use rustc::ty::TyCtxt; -use rustc_back::{LinkerFlavor, LldFlavor}; +use rustc_target::spec::{LinkerFlavor, LldFlavor}; use serialize::{json, Encoder}; /// For all the linkers we support, and information they might diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index a4e1b7f2925dc..2323ec3ef1108 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -74,7 +74,7 @@ use type_of::LayoutLlvmExt; use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet}; use CrateInfo; use rustc_data_structures::sync::Lrc; -use rustc_back::target::TargetTriple; +use rustc_target::spec::TargetTriple; use std::any::Any; use std::collections::BTreeMap; diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 2c503bdab30a9..5849437758af6 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -26,7 +26,7 @@ use rustc::hir::def_id::DefId; use rustc::ty::{self, TypeFoldable}; use rustc::ty::layout::LayoutOf; use rustc::ty::subst::Substs; -use rustc_back::PanicStrategy; +use rustc_target::spec::PanicStrategy; /// Translates a reference to a fn/method item, monomorphizing and /// inlining as it goes. diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index e83e73c8ae757..25ca2152b2768 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -32,7 +32,7 @@ use rustc::hir; use libc::{c_uint, c_char}; use std::iter; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::symbol::InternedString; use syntax_pos::{Span, DUMMY_SP}; diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 4d781d7280d37..76f8be9ee98a6 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -31,6 +31,7 @@ use rustc::session::Session; use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; +use rustc_target::spec::{HasTargetSpec, Target}; use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; @@ -453,13 +454,20 @@ impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CodegenCx<'a, 'tcx> { } } +impl<'a, 'tcx> HasTargetSpec for &'a CodegenCx<'a, 'tcx> { + fn target_spec(&self) -> &Target { + &self.tcx.sess.target.target + } +} + impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.tcx } } -impl<'a, 'tcx> LayoutOf> for &'a CodegenCx<'a, 'tcx> { +impl<'a, 'tcx> LayoutOf for &'a CodegenCx<'a, 'tcx> { + type Ty = Ty<'tcx>; type TyLayout = TyLayout<'tcx>; fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index eb550d7a605c5..5359e0e0405a1 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -32,7 +32,7 @@ use rustc::ich::Fingerprint; use rustc::ty::Instance; use common::CodegenCx; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; -use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; +use rustc::ty::layout::{self, Align, LayoutOf, PrimitiveExt, Size, TyLayout}; use rustc::session::config; use rustc::util::nodemap::FxHashMap; use rustc::util::common::path2cstr; diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index c2010feb1b638..bbe4e18b18cb1 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -24,8 +24,8 @@ use llvm::{self, ValueRef}; use llvm::AttributePlace::Function; use rustc::ty::{self, Ty}; use rustc::session::config::Sanitizer; -use rustc_back::PanicStrategy; -use abi::{Abi, FnType}; +use rustc_target::spec::PanicStrategy; +use abi::{Abi, FnType, FnTypeExt}; use attributes; use context::CodegenCx; use common; @@ -131,7 +131,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, debug!("declare_rust_fn (after region erasure) sig={:?}", sig); let fty = FnType::new(cx, sig, &[]); - let llfn = declare_raw_fn(cx, name, fty.cconv, fty.llvm_type(cx)); + let llfn = declare_raw_fn(cx, name, fty.llvm_cconv(), fty.llvm_type(cx)); // FIXME(canndrew): This is_never should really be an is_uninhabited if sig.output().is_never() { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index ecdc2d20d2142..103b04e6f135b 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -13,7 +13,7 @@ use intrinsics::{self, Intrinsic}; use llvm; use llvm::{ValueRef}; -use abi::{Abi, FnType, PassMode}; +use abi::{Abi, FnType, LlvmType, PassMode}; use mir::place::PlaceRef; use mir::operand::{OperandRef, OperandValue}; use base::*; @@ -87,7 +87,7 @@ fn get_simple_intrinsic(cx: &CodegenCx, name: &str) -> Option { /// add them to librustc_trans/trans/context.rs pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, callee_ty: Ty<'tcx>, - fn_ty: &FnType<'tcx>, + fn_ty: &FnType<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx>], llresult: ValueRef, span: Span) { diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 49d0f638f2061..dab01abd3353a 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -33,8 +33,6 @@ use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; -#[macro_use] -extern crate bitflags; extern crate flate2; extern crate libc; #[macro_use] extern crate rustc; @@ -43,7 +41,7 @@ extern crate num_cpus; extern crate rustc_mir; extern crate rustc_allocator; extern crate rustc_apfloat; -extern crate rustc_back; +extern crate rustc_target; extern crate rustc_const_math; #[macro_use] extern crate rustc_data_structures; extern crate rustc_demangle; @@ -104,24 +102,6 @@ mod asm; mod attributes; mod base; mod builder; -mod cabi_aarch64; -mod cabi_arm; -mod cabi_asmjs; -mod cabi_hexagon; -mod cabi_mips; -mod cabi_mips64; -mod cabi_msp430; -mod cabi_nvptx; -mod cabi_nvptx64; -mod cabi_powerpc; -mod cabi_powerpc64; -mod cabi_s390x; -mod cabi_sparc; -mod cabi_sparc64; -mod cabi_x86; -mod cabi_x86_64; -mod cabi_x86_win64; -mod cabi_wasm32; mod callee; mod common; mod consts; diff --git a/src/librustc_trans/metadata.rs b/src/librustc_trans/metadata.rs index 9483420f2f0e7..144baa65c1bfa 100644 --- a/src/librustc_trans/metadata.rs +++ b/src/librustc_trans/metadata.rs @@ -10,7 +10,7 @@ use rustc::util::common; use rustc::middle::cstore::MetadataLoader; -use rustc_back::target::Target; +use rustc_target::spec::Target; use llvm; use llvm::{False, ObjectFile, mk_section_iter}; use llvm::archive_ro::ArchiveRO; diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 6b542ae2e9364..21bbdf31dcb52 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::ValueRef; -use abi::FnType; +use abi::{FnType, FnTypeExt}; use callee; use common::*; use builder::Builder; @@ -35,7 +35,7 @@ impl<'a, 'tcx> VirtualIndex { pub fn get_fn(self, bx: &Builder<'a, 'tcx>, llvtable: ValueRef, - fn_ty: &FnType<'tcx>) -> ValueRef { + fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef { // Load the data pointer from the object. debug!("get_fn({:?}, {:?})", Value(llvtable), self); diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 93bc89f0914f5..36f03605feabd 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -10,10 +10,10 @@ use llvm::{self, ValueRef, BasicBlockRef}; use rustc::middle::lang_items; -use rustc::ty::{self, TypeFoldable}; +use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, LayoutOf}; use rustc::mir; -use abi::{Abi, FnType, ArgType, PassMode}; +use abi::{Abi, ArgType, ArgTypeExt, FnType, FnTypeExt, LlvmType, PassMode}; use base; use callee; use builder::Builder; @@ -110,7 +110,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { let do_call = | this: &mut Self, bx: Builder<'a, 'tcx>, - fn_ty: FnType<'tcx>, + fn_ty: FnType<'tcx, Ty<'tcx>>, fn_ptr: ValueRef, llargs: &[ValueRef], destination: Option<(ReturnDest<'tcx>, mir::BasicBlock)>, @@ -604,7 +604,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { bx: &Builder<'a, 'tcx>, op: OperandRef<'tcx>, llargs: &mut Vec, - arg: &ArgType<'tcx>) { + arg: &ArgType<'tcx, Ty<'tcx>>) { // Fill padding with undef value, where applicable. if let Some(ty) = arg.pad { llargs.push(C_undef(ty.llvm_type(bx.cx))); @@ -683,7 +683,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { bx: &Builder<'a, 'tcx>, operand: &mir::Operand<'tcx>, llargs: &mut Vec, - args: &[ArgType<'tcx>]) { + args: &[ArgType<'tcx, Ty<'tcx>>]) { let tuple = self.trans_operand(bx, operand); // Handle both by-ref and immediate tuples. @@ -776,7 +776,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } fn make_return_dest(&mut self, bx: &Builder<'a, 'tcx>, - dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx>, + dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>, llargs: &mut Vec, is_intrinsic: bool) -> ReturnDest<'tcx> { // If the return is ignored, we can just return a do-nothing ReturnDest @@ -873,7 +873,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { fn store_return(&mut self, bx: &Builder<'a, 'tcx>, dest: ReturnDest<'tcx>, - ret_ty: &ArgType<'tcx>, + ret_ty: &ArgType<'tcx, Ty<'tcx>>, llval: ValueRef) { use self::ReturnDest::*; diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index c55836919a97f..a074f25dfc9ba 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -12,7 +12,7 @@ use common::{C_i32, C_null}; use libc::c_uint; use llvm::{self, ValueRef, BasicBlockRef}; use llvm::debuginfo::DIScope; -use rustc::ty::{self, TypeFoldable}; +use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{LayoutOf, TyLayout}; use rustc::mir::{self, Mir}; use rustc::ty::subst::Substs; @@ -22,7 +22,7 @@ use builder::Builder; use common::{CodegenCx, Funclet}; use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext}; use monomorphize::Instance; -use abi::{ArgAttribute, FnType, PassMode}; +use abi::{ArgAttribute, ArgTypeExt, FnType, FnTypeExt, PassMode}; use type_::Type; use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span}; @@ -53,7 +53,7 @@ pub struct FunctionCx<'a, 'tcx:'a> { cx: &'a CodegenCx<'a, 'tcx>, - fn_ty: FnType<'tcx>, + fn_ty: FnType<'tcx, Ty<'tcx>>, /// When unwinding is initiated, we have to store this personality /// value somewhere so that we can load it and re-use it in the diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index f37114ee4acd1..5e6b276495764 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::FnType; +use abi::{FnType, FnTypeExt}; use common::*; use rustc::hir; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; -use rustc_back::PanicStrategy; +use rustc_target::spec::PanicStrategy; use trans_item::DefPathBasedNames; use type_::Type; diff --git a/src/librustc_trans_utils/Cargo.toml b/src/librustc_trans_utils/Cargo.toml index 7a01b6d261a34..323d9d1cedae0 100644 --- a/src/librustc_trans_utils/Cargo.toml +++ b/src/librustc_trans_utils/Cargo.toml @@ -17,7 +17,7 @@ log = "0.4" syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc = { path = "../librustc" } -rustc_back = { path = "../librustc_back" } +rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_mir = { path = "../librustc_mir" } rustc_incremental = { path = "../librustc_incremental" } diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 0c6bc9e246bce..b91f4e4dffb07 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -30,7 +30,7 @@ extern crate log; #[macro_use] extern crate rustc; -extern crate rustc_back; +extern crate rustc_target; extern crate rustc_mir; extern crate rustc_incremental; extern crate syntax; diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index b7895631c6092..7b585d1060fc2 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -43,7 +43,7 @@ use rustc::ty::maps::Providers; use rustc::middle::cstore::EncodedMetadata; use rustc::middle::cstore::MetadataLoader; use rustc::dep_graph::DepGraph; -use rustc_back::target::Target; +use rustc_target::spec::Target; use rustc_data_structures::fx::FxHashMap; use rustc_mir::monomorphize::collector; use link::{build_link_meta, out_filename}; diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index c7868cc1e9507..70c13e9b7d637 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -18,5 +18,6 @@ rustc = { path = "../librustc" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } +rustc_target = { path = "../librustc_target" } syntax_pos = { path = "../libsyntax_pos" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d657db0b1252c..6cdce127308f6 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -23,6 +23,7 @@ use rustc::ty::subst::{Kind, UnpackedKind, Subst, Substs}; use rustc::traits; use rustc::ty::{self, RegionKind, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::wf::object_region_bounds; +use rustc_target::spec::abi; use std::slice; use require_c_abi_if_variadic; use util::common::ErrorReported; @@ -30,7 +31,7 @@ use util::nodemap::FxHashSet; use errors::FatalError; use std::iter; -use syntax::{abi, ast}; +use syntax::ast; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax_pos::Span; diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 0c95f5eeb4311..4df496763e40a 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -17,7 +17,7 @@ use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::{infer, traits}; use rustc::ty::{self, TyCtxt, TypeFoldable, Ty}; use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; -use syntax::abi; +use rustc_target::spec::abi; use syntax::symbol::Symbol; use syntax_pos::Span; diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index ed0613860d03a..3b9d561ffc5a5 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -23,7 +23,7 @@ use rustc::ty::subst::Substs; use rustc::ty::TypeFoldable; use std::cmp; use std::iter; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::codemap::Span; use rustc::hir; diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 64b0e7d0a7d6e..283fbf8fecc42 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -17,7 +17,7 @@ use rustc::ty::{self, TyCtxt, Ty}; use rustc::util::nodemap::FxHashMap; use require_same_types; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::symbol::Symbol; use syntax_pos::Span; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4083d4a21ef4e..787df7c647969 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -118,7 +118,7 @@ use std::fmt::Display; use std::mem::replace; use std::iter; use std::ops::{self, Deref}; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr; use syntax::codemap::{original_sp, Spanned}; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index fb8c6ba6401d7..2ebbd64cab90e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -38,8 +38,9 @@ use rustc::ty::util::IntTypeExt; use rustc::ty::util::Discr; use rustc::util::captures::Captures; use rustc::util::nodemap::FxHashMap; +use rustc_target::spec::abi; -use syntax::{abi, ast}; +use syntax::ast; use syntax::ast::MetaItemKind; use syntax::attr::{InlineAttr, list_contains_name, mark_used}; use syntax::codemap::Spanned; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index d29ee3d9b3ab1..23fe91ffdebb6 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -94,6 +94,7 @@ extern crate rustc_platform_intrinsics as intrinsics; extern crate rustc_const_math; extern crate rustc_data_structures; extern crate rustc_errors as errors; +extern crate rustc_target; use rustc::hir; use rustc::lint; @@ -111,7 +112,7 @@ use session::{CompileIncomplete, config}; use util::common::time; use syntax::ast; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax_pos::Span; use std::iter; diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index 65c78d3593f63..26fba71c81285 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -23,7 +23,8 @@ use rustc::ty::{self, AdtKind, CratePredicatesMap, Region, RegionKind, ReprOptio ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; -use syntax::{abi, ast}; +use rustc_target::spec::abi; +use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; /// Infer predicates for the items in the crate. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e37b3a7fcc4d8..fb05cbfe32c70 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -20,7 +20,7 @@ pub use self::FunctionRetTy::*; pub use self::Visibility::*; use syntax; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast::{self, AttrStyle, Ident}; use syntax::attr; use syntax::codemap::{dummy_spanned, Spanned}; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2bd1e72f0eb17..d423203b99645 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -23,7 +23,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_resolve as resolve; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::CStore; -use rustc_back::target::TargetTriple; +use rustc_target::spec::TargetTriple; use syntax::ast::NodeId; use syntax::codemap; diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 413e5623118ac..f85a70a6d401f 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -13,7 +13,7 @@ pub use self::StructType::*; pub use self::TypeBound::*; -use syntax::abi; +use rustc_target::spec::abi; use syntax::ast; use syntax::ast::{Name, NodeId}; use syntax::attr; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0a7e19fc643f6..a9a4c5113747e 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -19,7 +19,7 @@ use std::fmt; use std::iter::repeat; use rustc::hir::def_id::DefId; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use rustc::hir; use clean::{self, PrimitiveType}; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 0ae946c418286..82449e9b5f90a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -54,7 +54,7 @@ use std::sync::Arc; use externalfiles::ExternalHtml; use serialize::json::{ToJson, Json, as_json}; -use syntax::{abi, ast}; +use syntax::ast; use syntax::codemap::FileName; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::middle::privacy::AccessLevels; @@ -62,6 +62,7 @@ use rustc::middle::stability; use rustc::hir; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::flock; +use rustc_target::spec::abi; use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability}; use doctree; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 60b713f2995e1..614386a583a77 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -35,8 +35,8 @@ extern crate rustc_trans_utils; extern crate rustc_driver; extern crate rustc_resolve; extern crate rustc_lint; -extern crate rustc_back; extern crate rustc_metadata; +extern crate rustc_target; extern crate rustc_typeck; extern crate serialize; #[macro_use] extern crate syntax; @@ -66,7 +66,7 @@ use externalfiles::ExternalHtml; use rustc::session::search_paths::SearchPaths; use rustc::session::config::{ErrorOutputType, RustcOptGroup, Externs, CodegenOptions}; use rustc::session::config::{nightly_options, build_codegen_options}; -use rustc_back::target::TargetTriple; +use rustc_target::spec::TargetTriple; #[macro_use] pub mod externalfiles; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f45a5b030db2b..967c50e62db5d 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -13,7 +13,7 @@ use std::mem; -use syntax::abi; +use rustc_target::spec::abi; use syntax::ast; use syntax::attr; use syntax_pos::Span; diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 8c24f36615bd2..d1a5ab0211b3b 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -14,6 +14,6 @@ serialize = { path = "../libserialize" } log = "0.4" scoped-tls = "0.1" syntax_pos = { path = "../libsyntax_pos" } -rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } rustc_errors = { path = "../librustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_target = { path = "../librustc_target" } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 4e3ee24146844..cbfcad12f1e52 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -19,7 +19,7 @@ pub use util::parser::ExprPrecedence; use syntax_pos::{Span, DUMMY_SP}; use codemap::{respan, Spanned}; -use abi::Abi; +use rustc_target::spec::abi::Abi; use ext::hygiene::{Mark, SyntaxContext}; use print::pprust; use ptr::P; diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index a9f483422434a..0b64189b2bc2b 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::Abi; +use rustc_target::spec::abi::Abi; use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind}; use attr; use syntax_pos::{Pos, Span, DUMMY_SP}; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 39ddb13d34788..0331e90164f0c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -25,7 +25,7 @@ use self::AttributeType::*; use self::AttributeGate::*; -use abi::Abi; +use rustc_target::spec::abi::Abi; use ast::{self, NodeId, PatKind, RangeEnd}; use attr; use edition::{ALL_EDITIONS, Edition}; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index ad98e2a6b71ad..870ce1926ade4 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -28,10 +28,6 @@ #![recursion_limit="256"] -// See librustc_cratesio_shim/Cargo.toml for a comment explaining this. -#[allow(unused_extern_crates)] -extern crate rustc_cratesio_shim; - #[macro_use] extern crate bitflags; extern crate core; extern crate serialize; @@ -39,6 +35,7 @@ extern crate serialize; pub extern crate rustc_errors as errors; extern crate syntax_pos; extern crate rustc_data_structures; +extern crate rustc_target; #[macro_use] extern crate scoped_tls; extern crate serialize as rustc_serialize; // used by deriving @@ -138,7 +135,6 @@ pub mod syntax { pub use ast; } -pub mod abi; pub mod ast; pub mod attr; pub mod codemap; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 0397c3297db0a..ff09c6aa2f006 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -678,7 +678,7 @@ mod tests { use syntax_pos::{self, Span, BytePos, Pos, NO_EXPANSION}; use codemap::{respan, Spanned}; use ast::{self, Ident, PatKind}; - use abi::Abi; + use rustc_target::spec::abi::Abi; use attr::first_attr_value_str_by_name; use parse; use parse::parser::Parser; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9fa3952ca80ca..324cadc84e862 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{self, Abi}; +use rustc_target::spec::abi::{self, Abi}; use ast::{AngleBracketedParameterData, ParenthesizedParameterData, AttrStyle, BareFnTy}; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::Unsafety; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bd06ae8c1a9b9..88860df10e2c3 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -10,7 +10,7 @@ pub use self::AnnNode::*; -use abi::{self, Abi}; +use rustc_target::spec::abi::{self, Abi}; use ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::Attribute; diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 325927ed83237..1734692f9e758 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -563,7 +563,9 @@ fn mk_main(cx: &mut TestCtxt) -> P { let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)), ast::Unsafety::Normal, dummy_spanned(ast::Constness::NotConst), - ::abi::Abi::Rust, ast::Generics::default(), main_body); + ::rustc_target::spec::abi::Abi::Rust, + ast::Generics::default(), + main_body); P(ast::Item { ident: Ident::from_str("main"), attrs: vec![main_attr], diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 8743840e44393..40d59d3ff8b8d 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -23,7 +23,7 @@ //! instance, a walker looking for item names in a module will miss all of //! those that are created by the expansion of a macro. -use abi::Abi; +use rustc_target::spec::abi::Abi; use ast::*; use syntax_pos::Span; use codemap::Spanned; diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml index d8eeb5ed2554a..1676757d9b89d 100644 --- a/src/libsyntax_ext/Cargo.toml +++ b/src/libsyntax_ext/Cargo.toml @@ -14,4 +14,5 @@ proc_macro = { path = "../libproc_macro" } rustc_errors = { path = "../librustc_errors" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rustc_data_structures = { path = "../librustc_data_structures" } \ No newline at end of file +rustc_data_structures = { path = "../librustc_data_structures" } +rustc_target = { path = "../librustc_target" } \ No newline at end of file diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 1ef0d2b0b4931..becd70149fd1e 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -191,7 +191,7 @@ use std::cell::RefCell; use std::collections::HashSet; use std::vec; -use syntax::abi::Abi; +use rustc_target::spec::abi::Abi; use syntax::ast::{ self, BinOpKind, EnumDef, Expr, GenericParam, Generics, Ident, PatKind, VariantData }; diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 39ad594e5c577..b6721dd28f367 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -27,6 +27,7 @@ extern crate syntax_pos; extern crate proc_macro; extern crate rustc_data_structures; extern crate rustc_errors as errors; +extern crate rustc_target; #[cfg(not(stage0))] mod diagnostics; diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml index bbc4c2ee43e07..9986e0b512a34 100644 --- a/src/rustc/Cargo.toml +++ b/src/rustc/Cargo.toml @@ -8,8 +8,8 @@ name = "rustc" path = "rustc.rs" [dependencies] -rustc_back = { path = "../librustc_back" } +rustc_target = { path = "../librustc_target" } rustc_driver = { path = "../librustc_driver" } [features] -jemalloc = ["rustc_back/jemalloc"] +jemalloc = ["rustc_target/jemalloc"]