Skip to content

Commit f8a968c

Browse files
committed
---
yaml --- r: 281994 b: refs/heads/stable c: c6d214b h: refs/heads/master
1 parent ded60c1 commit f8a968c

File tree

13 files changed

+319
-532
lines changed

13 files changed

+319
-532
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: e06d2ad9fcd5027bcaac5b08fc9aa39a49d0ecd3
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: 3c795e08d6f4a532f12f3f8e1837db5e0647f8b0
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 9221b9118b96d668e2cf5d701b10c0566aa072e9
32+
refs/heads/stable: c6d214bdeb1bfc9664ad14085c94bf2cbc5af6ee
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/librustc_trans/trans/cabi.rs

Lines changed: 173 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010

1111
pub use self::ArgKind::*;
1212

13-
use llvm::Attribute;
14-
use std::option;
13+
use llvm::{self, AttrHelper, ValueRef};
14+
use trans::attributes;
15+
use trans::common::return_type_is_void;
1516
use trans::context::CrateContext;
1617
use trans::cabi_x86;
1718
use trans::cabi_x86_64;
@@ -23,6 +24,11 @@ use trans::cabi_powerpc64;
2324
use trans::cabi_mips;
2425
use trans::cabi_asmjs;
2526
use trans::type_::Type;
27+
use trans::type_of;
28+
29+
use middle::ty::{self, Ty};
30+
31+
use syntax::abi::Abi;
2632

2733
#[derive(Clone, Copy, PartialEq, Debug)]
2834
pub enum ArgKind {
@@ -45,17 +51,17 @@ pub struct ArgType {
4551
/// Original LLVM type
4652
pub ty: Type,
4753
/// Coerced LLVM Type
48-
pub cast: option::Option<Type>,
54+
pub cast: Option<Type>,
4955
/// Dummy argument, which is emitted before the real argument
50-
pub pad: option::Option<Type>,
56+
pub pad: Option<Type>,
5157
/// LLVM attribute of argument
52-
pub attr: option::Option<Attribute>
58+
pub attr: Option<llvm::Attribute>
5359
}
5460

5561
impl ArgType {
56-
pub fn direct(ty: Type, cast: option::Option<Type>,
57-
pad: option::Option<Type>,
58-
attr: option::Option<Attribute>) -> ArgType {
62+
pub fn direct(ty: Type, cast: Option<Type>,
63+
pad: Option<Type>,
64+
attr: Option<llvm::Attribute>) -> ArgType {
5965
ArgType {
6066
kind: Direct,
6167
ty: ty,
@@ -65,12 +71,12 @@ impl ArgType {
6571
}
6672
}
6773

68-
pub fn indirect(ty: Type, attr: option::Option<Attribute>) -> ArgType {
74+
pub fn indirect(ty: Type, attr: Option<llvm::Attribute>) -> ArgType {
6975
ArgType {
7076
kind: Indirect,
7177
ty: ty,
72-
cast: option::Option::None,
73-
pad: option::Option::None,
78+
cast: Option::None,
79+
pad: Option::None,
7480
attr: attr
7581
}
7682
}
@@ -94,44 +100,175 @@ impl ArgType {
94100
}
95101
}
96102

103+
fn c_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Type {
104+
if ty.is_bool() {
105+
Type::i1(cx)
106+
} else {
107+
type_of::type_of(cx, ty)
108+
}
109+
}
110+
97111
/// Metadata describing how the arguments to a native function
98112
/// should be passed in order to respect the native ABI.
99113
///
100114
/// I will do my best to describe this structure, but these
101115
/// comments are reverse-engineered and may be inaccurate. -NDM
102116
pub struct FnType {
103117
/// The LLVM types of each argument.
104-
pub arg_tys: Vec<ArgType> ,
118+
pub args: Vec<ArgType>,
105119

106120
/// LLVM return type.
107-
pub ret_ty: ArgType,
121+
pub ret: ArgType,
122+
123+
pub variadic: bool,
124+
125+
pub cconv: llvm::CallConv
108126
}
109127

110-
pub fn compute_abi_info(ccx: &CrateContext,
111-
atys: &[Type],
112-
rty: Type,
113-
ret_def: bool) -> FnType {
114-
match &ccx.sess().target.target.arch[..] {
115-
"x86" => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def),
116-
"x86_64" => if ccx.sess().target.target.options.is_like_windows {
117-
cabi_x86_win64::compute_abi_info(ccx, atys, rty, ret_def)
128+
impl FnType {
129+
pub fn new<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
130+
abi: Abi,
131+
sig: &ty::FnSig<'tcx>,
132+
extra_args: &[Ty<'tcx>]) -> FnType {
133+
use syntax::abi::Abi::*;
134+
let cconv = match ccx.sess().target.target.adjust_abi(abi) {
135+
RustIntrinsic => {
136+
// Intrinsics are emitted at the call site
137+
ccx.sess().bug("asked to register intrinsic fn");
138+
}
139+
PlatformIntrinsic => {
140+
// Intrinsics are emitted at the call site
141+
ccx.sess().bug("asked to register platform intrinsic fn");
142+
}
143+
144+
Rust => {
145+
// FIXME(#3678) Implement linking to foreign fns with Rust ABI
146+
ccx.sess().unimpl("foreign functions with Rust ABI");
147+
}
148+
149+
RustCall => {
150+
// FIXME(#3678) Implement linking to foreign fns with Rust ABI
151+
ccx.sess().unimpl("foreign functions with RustCall ABI");
152+
}
153+
154+
// It's the ABI's job to select this, not us.
155+
System => ccx.sess().bug("system abi should be selected elsewhere"),
156+
157+
Stdcall => llvm::X86StdcallCallConv,
158+
Fastcall => llvm::X86FastcallCallConv,
159+
Vectorcall => llvm::X86_VectorCall,
160+
C => llvm::CCallConv,
161+
Win64 => llvm::X86_64_Win64,
162+
163+
// These API constants ought to be more specific...
164+
Cdecl => llvm::CCallConv,
165+
Aapcs => llvm::CCallConv,
166+
};
167+
168+
let rty = match sig.output {
169+
ty::FnConverging(ret_ty) if !return_type_is_void(ccx, ret_ty) => {
170+
c_type_of(ccx, ret_ty)
171+
}
172+
_ => Type::void(ccx)
173+
};
174+
175+
let mut fty = FnType {
176+
args: sig.inputs.iter().chain(extra_args.iter()).map(|&ty| {
177+
ArgType::direct(c_type_of(ccx, ty), None, None, None)
178+
}).collect(),
179+
ret: ArgType::direct(rty, None, None, None),
180+
variadic: sig.variadic,
181+
cconv: cconv
182+
};
183+
184+
match &ccx.sess().target.target.arch[..] {
185+
"x86" => cabi_x86::compute_abi_info(ccx, &mut fty),
186+
"x86_64" => if ccx.sess().target.target.options.is_like_windows {
187+
cabi_x86_win64::compute_abi_info(ccx, &mut fty);
188+
} else {
189+
cabi_x86_64::compute_abi_info(ccx, &mut fty);
190+
},
191+
"aarch64" => cabi_aarch64::compute_abi_info(ccx, &mut fty),
192+
"arm" => {
193+
let flavor = if ccx.sess().target.target.target_os == "ios" {
194+
cabi_arm::Flavor::Ios
195+
} else {
196+
cabi_arm::Flavor::General
197+
};
198+
cabi_arm::compute_abi_info(ccx, &mut fty, flavor);
199+
},
200+
"mips" => cabi_mips::compute_abi_info(ccx, &mut fty),
201+
"powerpc" => cabi_powerpc::compute_abi_info(ccx, &mut fty),
202+
"powerpc64" => cabi_powerpc64::compute_abi_info(ccx, &mut fty),
203+
"asmjs" => cabi_asmjs::compute_abi_info(ccx, &mut fty),
204+
a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a))
205+
}
206+
207+
fty
208+
}
209+
210+
pub fn to_llvm(&self, ccx: &CrateContext) -> Type {
211+
let mut llargument_tys = Vec::new();
212+
213+
let llreturn_ty = if self.ret.is_indirect() {
214+
llargument_tys.push(self.ret.ty.ptr_to());
215+
Type::void(ccx)
118216
} else {
119-
cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def)
120-
},
121-
"aarch64" => cabi_aarch64::compute_abi_info(ccx, atys, rty, ret_def),
122-
"arm" => {
123-
let flavor = if ccx.sess().target.target.target_os == "ios" {
124-
cabi_arm::Flavor::Ios
217+
self.ret.cast.unwrap_or(self.ret.ty)
218+
};
219+
220+
for arg in &self.args {
221+
if arg.is_ignore() {
222+
continue;
223+
}
224+
// add padding
225+
if let Some(ty) = arg.pad {
226+
llargument_tys.push(ty);
227+
}
228+
229+
let llarg_ty = if arg.is_indirect() {
230+
arg.ty.ptr_to()
125231
} else {
126-
cabi_arm::Flavor::General
232+
arg.cast.unwrap_or(arg.ty)
127233
};
128-
cabi_arm::compute_abi_info(ccx, atys, rty, ret_def, flavor)
129-
},
130-
"mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
131-
"powerpc" => cabi_powerpc::compute_abi_info(ccx, atys, rty, ret_def),
132-
"powerpc64" => cabi_powerpc64::compute_abi_info(ccx, atys, rty, ret_def),
133-
"asmjs" => cabi_asmjs::compute_abi_info(ccx, atys, rty, ret_def),
134-
a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)
135-
),
234+
235+
llargument_tys.push(llarg_ty);
236+
}
237+
238+
if self.variadic {
239+
Type::variadic_func(&llargument_tys, &llreturn_ty)
240+
} else {
241+
Type::func(&llargument_tys, &llreturn_ty)
242+
}
243+
}
244+
245+
pub fn add_attributes(&self, llfn: ValueRef) {
246+
let mut i = if self.ret.is_indirect() {
247+
1
248+
} else {
249+
0
250+
};
251+
252+
if let Some(attr) = self.ret.attr {
253+
attr.apply_llfn(i, llfn);
254+
}
255+
256+
i += 1;
257+
258+
for arg in &self.args {
259+
if arg.is_ignore() {
260+
continue;
261+
}
262+
// skip padding
263+
if arg.pad.is_some() { i += 1; }
264+
265+
if let Some(attr) = arg.attr {
266+
attr.apply_llfn(i, llfn);
267+
}
268+
269+
i += 1;
270+
}
271+
272+
attributes::unwind(llfn, false);
136273
}
137274
}

branches/stable/src/librustc_trans/trans/cabi_aarch64.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -228,24 +228,12 @@ fn is_reg_ty(ty: Type) -> bool {
228228
}
229229
}
230230

231-
pub fn compute_abi_info(ccx: &CrateContext,
232-
atys: &[Type],
233-
rty: Type,
234-
ret_def: bool) -> FnType {
235-
let mut arg_tys = Vec::new();
236-
for &aty in atys {
237-
let ty = classify_arg_ty(ccx, aty);
238-
arg_tys.push(ty);
231+
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
232+
if fty.ret.ty != Type::void(ccx) {
233+
fty.ret = classify_ret_ty(ccx, fty.ret.ty);
239234
}
240235

241-
let ret_ty = if ret_def {
242-
classify_ret_ty(ccx, rty)
243-
} else {
244-
ArgType::direct(Type::void(ccx), None, None, None)
245-
};
246-
247-
return FnType {
248-
arg_tys: arg_tys,
249-
ret_ty: ret_ty,
250-
};
236+
for arg in &mut fty.args {
237+
*arg = classify_arg_ty(ccx, arg.ty);
238+
}
251239
}

branches/stable/src/librustc_trans/trans/cabi_arm.rs

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -174,30 +174,17 @@ fn is_reg_ty(ty: Type) -> bool {
174174
}
175175
}
176176

177-
pub fn compute_abi_info(ccx: &CrateContext,
178-
atys: &[Type],
179-
rty: Type,
180-
ret_def: bool,
181-
flavor: Flavor) -> FnType {
177+
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType, flavor: Flavor) {
182178
let align_fn = match flavor {
183179
Flavor::General => general_ty_align as TyAlignFn,
184180
Flavor::Ios => ios_ty_align as TyAlignFn,
185181
};
186182

187-
let mut arg_tys = Vec::new();
188-
for &aty in atys {
189-
let ty = classify_arg_ty(ccx, aty, align_fn);
190-
arg_tys.push(ty);
183+
if fty.ret.ty != Type::void(ccx) {
184+
fty.ret = classify_ret_ty(ccx, fty.ret.ty, align_fn);
191185
}
192186

193-
let ret_ty = if ret_def {
194-
classify_ret_ty(ccx, rty, align_fn)
195-
} else {
196-
ArgType::direct(Type::void(ccx), None, None, None)
197-
};
198-
199-
return FnType {
200-
arg_tys: arg_tys,
201-
ret_ty: ret_ty,
202-
};
187+
for arg in &mut fty.args {
188+
*arg = classify_arg_ty(ccx, arg.ty, align_fn);
189+
}
203190
}

branches/stable/src/librustc_trans/trans/cabi_asmjs.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,12 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
4949
}
5050
}
5151

52-
pub fn compute_abi_info(ccx: &CrateContext,
53-
atys: &[Type],
54-
rty: Type,
55-
ret_def: bool) -> FnType {
56-
let mut arg_tys = Vec::new();
57-
for &aty in atys {
58-
let ty = classify_arg_ty(ccx, aty);
59-
arg_tys.push(ty);
52+
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
53+
if fty.ret.ty != Type::void(ccx) {
54+
fty.ret = classify_ret_ty(ccx, fty.ret.ty);
6055
}
6156

62-
let ret_ty = if ret_def {
63-
classify_ret_ty(ccx, rty)
64-
} else {
65-
ArgType::direct(Type::void(ccx), None, None, None)
66-
};
67-
68-
return FnType {
69-
arg_tys: arg_tys,
70-
ret_ty: ret_ty,
71-
};
57+
for arg in &mut fty.args {
58+
*arg = classify_arg_ty(ccx, arg.ty);
59+
}
7260
}

0 commit comments

Comments
 (0)