Skip to content

Commit fb15d44

Browse files
committed
rustc_trans: generalize cabi_* to any context type.
1 parent c45dda9 commit fb15d44

22 files changed

+303
-178
lines changed

src/librustc_target/abi/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -784,18 +784,18 @@ pub trait LayoutOf {
784784
fn layout_of(self, ty: Self::Ty) -> Self::TyLayout;
785785
}
786786

787-
pub trait TyLayoutMethods<'a, C: LayoutOf>: Sized {
787+
pub trait TyLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {
788788
fn for_variant(this: TyLayout<'a, Self>, cx: C, variant_index: usize) -> TyLayout<'a, Self>;
789789
fn field(this: TyLayout<'a, Self>, cx: C, i: usize) -> C::TyLayout;
790790
}
791791

792792
impl<'a, Ty> TyLayout<'a, Ty> {
793793
pub fn for_variant<C>(self, cx: C, variant_index: usize) -> Self
794-
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf {
794+
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> {
795795
Ty::for_variant(self, cx, variant_index)
796796
}
797797
pub fn field<C>(self, cx: C, i: usize) -> C::TyLayout
798-
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf {
798+
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> {
799799
Ty::field(self, cx, i)
800800
}
801801
}

src/librustc_target/spec/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,16 @@ pub struct Target {
397397
pub options: TargetOptions,
398398
}
399399

400+
pub trait HasTargetSpec: Copy {
401+
fn target_spec(&self) -> &Target;
402+
}
403+
404+
impl<'a> HasTargetSpec for &'a Target {
405+
fn target_spec(&self) -> &Target {
406+
self
407+
}
408+
}
409+
400410
/// Optional aspects of a target specification.
401411
///
402412
/// This has an implementation of `Default`, see each field for what the default is. In general,

src/librustc_trans/abi.rs

+43-21
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ use mir::operand::OperandValue;
3636
use type_::Type;
3737
use type_of::{LayoutLlvmExt, PointerKind};
3838

39+
use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods};
40+
use rustc_target::spec::HasTargetSpec;
3941
use rustc::ty::{self, Ty};
40-
use rustc::ty::layout::{self, LayoutOf, Size, TyLayout};
42+
use rustc::ty::layout;
4143

4244
use libc::c_uint;
4345
use std::cmp;
@@ -142,12 +144,13 @@ impl LlvmType for Reg {
142144
}
143145
}
144146

145-
pub trait LayoutExt<'tcx> {
147+
pub trait LayoutExt<'a, Ty>: Sized {
146148
fn is_aggregate(&self) -> bool;
147-
fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option<Reg>;
149+
fn homogeneous_aggregate<C>(&self, cx: C) -> Option<Reg>
150+
where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf<Ty = Ty, TyLayout = Self> + Copy;
148151
}
149152

150-
impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> {
153+
impl<'a, Ty> LayoutExt<'a, Ty> for TyLayout<'a, Ty> {
151154
fn is_aggregate(&self) -> bool {
152155
match self.abi {
153156
layout::Abi::Uninhabited |
@@ -158,7 +161,9 @@ impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> {
158161
}
159162
}
160163

161-
fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option<Reg> {
164+
fn homogeneous_aggregate<C>(&self, cx: C) -> Option<Reg>
165+
where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf<Ty = Ty, TyLayout = Self> + Copy
166+
{
162167
match self.abi {
163168
layout::Abi::Uninhabited => None,
164169

@@ -280,17 +285,17 @@ impl LlvmType for CastTarget {
280285
/// Information about how to pass an argument to,
281286
/// or return a value from, a function, under some ABI.
282287
#[derive(Debug)]
283-
pub struct ArgType<'tcx> {
284-
pub layout: TyLayout<'tcx>,
288+
pub struct ArgType<'tcx, Ty = ty::Ty<'tcx>> {
289+
pub layout: TyLayout<'tcx, Ty>,
285290

286291
/// Dummy argument, which is emitted before the real argument.
287292
pub pad: Option<Reg>,
288293

289294
pub mode: PassMode,
290295
}
291296

292-
impl<'a, 'tcx> ArgType<'tcx> {
293-
fn new(layout: TyLayout<'tcx>) -> ArgType<'tcx> {
297+
impl<'a, 'tcx, Ty> ArgType<'tcx, Ty> {
298+
fn new(layout: TyLayout<'tcx, Ty>) -> Self {
294299
ArgType {
295300
layout,
296301
pad: None,
@@ -364,7 +369,9 @@ impl<'a, 'tcx> ArgType<'tcx> {
364369
pub fn is_ignore(&self) -> bool {
365370
self.mode == PassMode::Ignore
366371
}
372+
}
367373

374+
impl<'a, 'tcx> ArgType<'tcx> {
368375
/// Get the LLVM type for a place of the original Rust type of
369376
/// this argument/return, i.e. the result of `type_of::type_of`.
370377
pub fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
@@ -451,12 +458,12 @@ impl<'a, 'tcx> ArgType<'tcx> {
451458
/// I will do my best to describe this structure, but these
452459
/// comments are reverse-engineered and may be inaccurate. -NDM
453460
#[derive(Debug)]
454-
pub struct FnType<'tcx> {
461+
pub struct FnType<'tcx, Ty = ty::Ty<'tcx>> {
455462
/// The LLVM types of each argument.
456-
pub args: Vec<ArgType<'tcx>>,
463+
pub args: Vec<ArgType<'tcx, Ty>>,
457464

458465
/// LLVM return type.
459-
pub ret: ArgType<'tcx>,
466+
pub ret: ArgType<'tcx, Ty>,
460467

461468
pub variadic: bool,
462469

@@ -474,15 +481,15 @@ impl<'a, 'tcx> FnType<'tcx> {
474481

475482
pub fn new(cx: &CodegenCx<'a, 'tcx>,
476483
sig: ty::FnSig<'tcx>,
477-
extra_args: &[Ty<'tcx>]) -> FnType<'tcx> {
484+
extra_args: &[Ty<'tcx>]) -> Self {
478485
let mut fn_ty = FnType::unadjusted(cx, sig, extra_args);
479486
fn_ty.adjust_for_abi(cx, sig.abi);
480487
fn_ty
481488
}
482489

483490
pub fn new_vtable(cx: &CodegenCx<'a, 'tcx>,
484491
sig: ty::FnSig<'tcx>,
485-
extra_args: &[Ty<'tcx>]) -> FnType<'tcx> {
492+
extra_args: &[Ty<'tcx>]) -> Self {
486493
let mut fn_ty = FnType::unadjusted(cx, sig, extra_args);
487494
// Don't pass the vtable, it's not an argument of the virtual fn.
488495
{
@@ -507,7 +514,7 @@ impl<'a, 'tcx> FnType<'tcx> {
507514

508515
pub fn unadjusted(cx: &CodegenCx<'a, 'tcx>,
509516
sig: ty::FnSig<'tcx>,
510-
extra_args: &[Ty<'tcx>]) -> FnType<'tcx> {
517+
extra_args: &[Ty<'tcx>]) -> Self {
511518
debug!("FnType::unadjusted({:?}, {:?})", sig, extra_args);
512519

513520
use self::Abi::*;
@@ -569,7 +576,7 @@ impl<'a, 'tcx> FnType<'tcx> {
569576
// Handle safe Rust thin and fat pointers.
570577
let adjust_for_rust_scalar = |attrs: &mut ArgAttributes,
571578
scalar: &layout::Scalar,
572-
layout: TyLayout<'tcx>,
579+
layout: TyLayout<'tcx, Ty<'tcx>>,
573580
offset: Size,
574581
is_return: bool| {
575582
// Booleans are always an i1 that needs to be zero-extended.
@@ -742,7 +749,18 @@ impl<'a, 'tcx> FnType<'tcx> {
742749
return;
743750
}
744751

745-
match &cx.sess().target.target.arch[..] {
752+
if let Err(msg) = self.adjust_for_cabi(cx, abi) {
753+
cx.sess().fatal(&msg);
754+
}
755+
}
756+
}
757+
758+
impl<'a, Ty> FnType<'a, Ty> {
759+
fn adjust_for_cabi<C>(&mut self, cx: C, abi: Abi) -> Result<(), String>
760+
where Ty: TyLayoutMethods<'a, C> + Copy,
761+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec
762+
{
763+
match &cx.target_spec().arch[..] {
746764
"x86" => {
747765
let flavor = if abi == Abi::Fastcall {
748766
cabi_x86::Flavor::Fastcall
@@ -753,7 +771,7 @@ impl<'a, 'tcx> FnType<'tcx> {
753771
},
754772
"x86_64" => if abi == Abi::SysV64 {
755773
cabi_x86_64::compute_abi_info(cx, self);
756-
} else if abi == Abi::Win64 || cx.sess().target.target.options.is_like_windows {
774+
} else if abi == Abi::Win64 || cx.target_spec().options.is_like_windows {
757775
cabi_x86_win64::compute_abi_info(self);
758776
} else {
759777
cabi_x86_64::compute_abi_info(cx, self);
@@ -767,10 +785,10 @@ impl<'a, 'tcx> FnType<'tcx> {
767785
"s390x" => cabi_s390x::compute_abi_info(cx, self),
768786
"asmjs" => cabi_asmjs::compute_abi_info(cx, self),
769787
"wasm32" => {
770-
if cx.sess().opts.target_triple.triple().contains("emscripten") {
788+
if cx.target_spec().llvm_target.contains("emscripten") {
771789
cabi_asmjs::compute_abi_info(cx, self)
772790
} else {
773-
cabi_wasm32::compute_abi_info(cx, self)
791+
cabi_wasm32::compute_abi_info(self)
774792
}
775793
}
776794
"msp430" => cabi_msp430::compute_abi_info(self),
@@ -779,14 +797,18 @@ impl<'a, 'tcx> FnType<'tcx> {
779797
"nvptx" => cabi_nvptx::compute_abi_info(self),
780798
"nvptx64" => cabi_nvptx64::compute_abi_info(self),
781799
"hexagon" => cabi_hexagon::compute_abi_info(self),
782-
a => cx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a))
800+
a => return Err(format!("unrecognized arch \"{}\" in target specification", a))
783801
}
784802

785803
if let PassMode::Indirect(ref mut attrs) = self.ret.mode {
786804
attrs.set(ArgAttribute::StructRet);
787805
}
806+
807+
Ok(())
788808
}
809+
}
789810

811+
impl<'a, 'tcx> FnType<'tcx> {
790812
pub fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
791813
let mut llargument_tys = Vec::new();
792814

src/librustc_trans/cabi_aarch64.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
// except according to those terms.
1010

1111
use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform};
12-
use context::CodegenCx;
12+
use rustc_target::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
1313

14-
fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>)
15-
-> Option<Uniform> {
14+
fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
15+
-> Option<Uniform>
16+
where Ty: TyLayoutMethods<'a, C> + Copy,
17+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
18+
{
1619
arg.layout.homogeneous_aggregate(cx).and_then(|unit| {
1720
let size = arg.layout.size;
1821

@@ -38,7 +41,10 @@ fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgTyp
3841
})
3942
}
4043

41-
fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) {
44+
fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>)
45+
where Ty: TyLayoutMethods<'a, C> + Copy,
46+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
47+
{
4248
if !ret.layout.is_aggregate() {
4349
ret.extend_integer_width_to(32);
4450
return;
@@ -69,7 +75,10 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>)
6975
ret.make_indirect();
7076
}
7177

72-
fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) {
78+
fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
79+
where Ty: TyLayoutMethods<'a, C> + Copy,
80+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
81+
{
7382
if !arg.layout.is_aggregate() {
7483
arg.extend_integer_width_to(32);
7584
return;
@@ -100,7 +109,10 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>)
100109
arg.make_indirect();
101110
}
102111

103-
pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) {
112+
pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
113+
where Ty: TyLayoutMethods<'a, C> + Copy,
114+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
115+
{
104116
if !fty.ret.is_ignore() {
105117
classify_ret_ty(cx, &mut fty.ret);
106118
}

src/librustc_trans/cabi_arm.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@
99
// except according to those terms.
1010

1111
use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform};
12-
use context::CodegenCx;
12+
use rustc_target::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
13+
use rustc_target::spec::HasTargetSpec;
1314
use llvm::CallConv;
1415

15-
fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>)
16-
-> Option<Uniform> {
16+
fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
17+
-> Option<Uniform>
18+
where Ty: TyLayoutMethods<'a, C> + Copy,
19+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
20+
{
1721
arg.layout.homogeneous_aggregate(cx).and_then(|unit| {
1822
let size = arg.layout.size;
1923

@@ -39,7 +43,10 @@ fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgTyp
3943
})
4044
}
4145

42-
fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, vfp: bool) {
46+
fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>, vfp: bool)
47+
where Ty: TyLayoutMethods<'a, C> + Copy,
48+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
49+
{
4350
if !ret.layout.is_aggregate() {
4451
ret.extend_integer_width_to(32);
4552
return;
@@ -71,7 +78,10 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>,
7178
ret.make_indirect();
7279
}
7380

74-
fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, vfp: bool) {
81+
fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>, vfp: bool)
82+
where Ty: TyLayoutMethods<'a, C> + Copy,
83+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
84+
{
7585
if !arg.layout.is_aggregate() {
7686
arg.extend_integer_width_to(32);
7787
return;
@@ -92,10 +102,13 @@ fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>,
92102
});
93103
}
94104

95-
pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) {
105+
pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
106+
where Ty: TyLayoutMethods<'a, C> + Copy,
107+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec
108+
{
96109
// If this is a target with a hard-float ABI, and the function is not explicitly
97110
// `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates.
98-
let vfp = cx.sess().target.target.llvm_target.ends_with("hf")
111+
let vfp = cx.target_spec().llvm_target.ends_with("hf")
99112
&& fty.cconv != CallConv::ArmAapcsCallConv
100113
&& !fty.variadic;
101114

src/librustc_trans/cabi_asmjs.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@
99
// except according to those terms.
1010

1111
use abi::{FnType, ArgType, LayoutExt, Uniform};
12-
use context::CodegenCx;
12+
use rustc_target::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
1313

1414
// Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128
1515

1616
// See the https://github.com/kripken/emscripten-fastcomp-clang repository.
1717
// The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions.
1818

19-
fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) {
19+
fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>)
20+
where Ty: TyLayoutMethods<'a, C> + Copy,
21+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
22+
{
2023
if ret.layout.is_aggregate() {
2124
if let Some(unit) = ret.layout.homogeneous_aggregate(cx) {
2225
let size = ret.layout.size;
@@ -33,13 +36,16 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>)
3336
}
3437
}
3538

36-
fn classify_arg_ty(arg: &mut ArgType) {
39+
fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>) {
3740
if arg.layout.is_aggregate() {
3841
arg.make_indirect_byval();
3942
}
4043
}
4144

42-
pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) {
45+
pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
46+
where Ty: TyLayoutMethods<'a, C> + Copy,
47+
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
48+
{
4349
if !fty.ret.is_ignore() {
4450
classify_ret_ty(cx, &mut fty.ret);
4551
}

0 commit comments

Comments
 (0)