Skip to content

Commit 925735a

Browse files
committed
---
yaml --- r: 146428 b: refs/heads/try2 c: 379bda9 h: refs/heads/master v: v3
1 parent 0fc1cee commit 925735a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+900
-214
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 4b9c5d6878522a23d97db14ff85b6bdc6e2edd84
8+
refs/heads/try2: 379bda9e527809fcf149383ac52c4afd1328c649
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/librustc/lib/llvm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub static False: Bool = 0 as Bool;
2929

3030
// Consts for the LLVM CallConv type, pre-cast to uint.
3131

32+
#[deriving(Eq)]
3233
pub enum CallConv {
3334
CCallConv = 0,
3435
FastCallConv = 8,

branches/try2/src/librustc/metadata/tydecode.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,10 +526,17 @@ fn parse_sig(st: &mut PState, conv: conv_did) -> ty::FnSig {
526526
inputs.push(parse_ty(st, |x,y| conv(x,y)));
527527
}
528528
st.pos += 1u; // eat the ']'
529+
let variadic = if peek(st) == 'A' {
530+
st.pos += 1; // eat the 'A'
531+
true
532+
} else { false };
529533
let ret_ty = parse_ty(st, conv);
530-
ty::FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
531-
inputs: inputs,
532-
output: ret_ty}
534+
ty::FnSig {
535+
bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
536+
inputs: inputs,
537+
output: ret_ty,
538+
variadic: variadic
539+
}
533540
}
534541

535542
// Rust metadata parsing

branches/try2/src/librustc/metadata/tyencode.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,9 @@ fn enc_fn_sig(w: @mut MemWriter, cx: @ctxt, fsig: &ty::FnSig) {
371371
enc_ty(w, cx, *ty);
372372
}
373373
mywrite!(w, "]");
374+
if fsig.variadic {
375+
mywrite!(w, "A");
376+
}
374377
enc_ty(w, cx, fsig.output);
375378
}
376379

branches/try2/src/librustc/middle/trans/callee.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,12 @@ pub fn trans_call_inner(in_cx: @mut Block,
750750
let mut llargs = ~[];
751751
bcx = trans_args(bcx, args, callee_ty,
752752
autoref_arg, &mut llargs);
753+
let arg_tys = match args {
754+
ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, *x)).collect(),
755+
ArgVals(_) => fail!("expected arg exprs.")
756+
};
753757
bcx = foreign::trans_native_call(bcx, callee_ty,
754-
llfn, opt_llretslot.unwrap(), llargs);
758+
llfn, opt_llretslot.unwrap(), llargs, arg_tys);
755759
}
756760

757761
// If the caller doesn't care about the result of this fn call,
@@ -789,6 +793,7 @@ pub fn trans_args(cx: @mut Block,
789793
let _icx = push_ctxt("trans_args");
790794
let mut temp_cleanups = ~[];
791795
let arg_tys = ty::ty_fn_args(fn_ty);
796+
let variadic = ty::fn_is_variadic(fn_ty);
792797

793798
let mut bcx = cx;
794799

@@ -797,10 +802,17 @@ pub fn trans_args(cx: @mut Block,
797802
// to cast her view of the arguments to the caller's view.
798803
match args {
799804
ArgExprs(arg_exprs) => {
805+
let num_formal_args = arg_tys.len();
800806
for (i, arg_expr) in arg_exprs.iter().enumerate() {
807+
let arg_ty = if i >= num_formal_args {
808+
assert!(variadic);
809+
expr_ty_adjusted(cx, *arg_expr)
810+
} else {
811+
arg_tys[i]
812+
};
801813
let arg_val = unpack_result!(bcx, {
802814
trans_arg_expr(bcx,
803-
arg_tys[i],
815+
arg_ty,
804816
ty::ByCopy,
805817
*arg_expr,
806818
&mut temp_cleanups,

branches/try2/src/librustc/middle/trans/foreign.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,7 @@ pub fn register_foreign_item_fn(ccx: @mut CrateContext,
120120
let cc = match llvm_calling_convention(ccx, abis) {
121121
Some(cc) => cc,
122122
None => {
123-
// FIXME(#8357) We really ought to report a span here
124-
ccx.sess.fatal(
123+
ccx.sess.span_fatal(foreign_item.span,
125124
format!("ABI `{}` has no suitable ABI \
126125
for target architecture \
127126
in module {}",
@@ -135,6 +134,12 @@ pub fn register_foreign_item_fn(ccx: @mut CrateContext,
135134
let lname = link_name(ccx, foreign_item);
136135
let tys = foreign_types_for_id(ccx, foreign_item.id);
137136

137+
// Make sure the calling convention is right for variadic functions
138+
// (should've been caught if not in typeck)
139+
if tys.fn_sig.variadic {
140+
assert!(cc == lib::llvm::CCallConv);
141+
}
142+
138143
// Create the LLVM value for the C extern fn
139144
let llfn_ty = lltype_for_fn_from_foreign_types(&tys);
140145
let llfn = base::get_extern_fn(&mut ccx.externs, ccx.llmod,
@@ -148,7 +153,8 @@ pub fn trans_native_call(bcx: @mut Block,
148153
callee_ty: ty::t,
149154
llfn: ValueRef,
150155
llretptr: ValueRef,
151-
llargs_rust: &[ValueRef]) -> @mut Block {
156+
llargs_rust: &[ValueRef],
157+
passed_arg_tys: ~[ty::t]) -> @mut Block {
152158
/*!
153159
* Prepares a call to a native function. This requires adapting
154160
* from the Rust argument passing rules to the native rules.
@@ -160,6 +166,10 @@ pub fn trans_native_call(bcx: @mut Block,
160166
* - `llretptr`: where to store the return value of the function
161167
* - `llargs_rust`: a list of the argument values, prepared
162168
* as they would be if calling a Rust function
169+
* - `passed_arg_tys`: Rust type for the arguments. Normally we
170+
* can derive these from callee_ty but in the case of variadic
171+
* functions passed_arg_tys will include the Rust type of all
172+
* the arguments including the ones not specified in the fn's signature.
163173
*/
164174

165175
let ccx = bcx.ccx();
@@ -176,7 +186,7 @@ pub fn trans_native_call(bcx: @mut Block,
176186
ty::ty_bare_fn(ref fn_ty) => (fn_ty.abis, fn_ty.sig.clone()),
177187
_ => ccx.sess.bug("trans_native_call called on non-function type")
178188
};
179-
let llsig = foreign_signature(ccx, &fn_sig);
189+
let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys);
180190
let ret_def = !ty::type_is_voidish(bcx.tcx(), fn_sig.output);
181191
let fn_type = cabi::compute_abi_info(ccx,
182192
llsig.llarg_tys,
@@ -208,7 +218,7 @@ pub fn trans_native_call(bcx: @mut Block,
208218
let mut llarg_rust = llarg_rust;
209219

210220
// Does Rust pass this argument by pointer?
211-
let rust_indirect = type_of::arg_is_indirect(ccx, fn_sig.inputs[i]);
221+
let rust_indirect = type_of::arg_is_indirect(ccx, passed_arg_tys[i]);
212222

213223
debug!("argument {}, llarg_rust={}, rust_indirect={}, arg_ty={}",
214224
i,
@@ -219,7 +229,7 @@ pub fn trans_native_call(bcx: @mut Block,
219229
// Ensure that we always have the Rust value indirectly,
220230
// because it makes bitcasting easier.
221231
if !rust_indirect {
222-
let scratch = base::alloca(bcx, type_of::type_of(ccx, fn_sig.inputs[i]), "__arg");
232+
let scratch = base::alloca(bcx, type_of::type_of(ccx, passed_arg_tys[i]), "__arg");
223233
Store(bcx, llarg_rust, scratch);
224234
llarg_rust = scratch;
225235
}
@@ -331,6 +341,20 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
331341
foreign_mod: &ast::foreign_mod) {
332342
let _icx = push_ctxt("foreign::trans_foreign_mod");
333343
for &foreign_item in foreign_mod.items.iter() {
344+
match foreign_item.node {
345+
ast::foreign_item_fn(*) => {
346+
let (abis, mut path) = match ccx.tcx.items.get_copy(&foreign_item.id) {
347+
ast_map::node_foreign_item(_, abis, _, path) => (abis, (*path).clone()),
348+
_ => fail!("Unable to find foreign item in tcx.items table.")
349+
};
350+
if !(abis.is_rust() || abis.is_intrinsic()) {
351+
path.push(ast_map::path_name(foreign_item.ident));
352+
register_foreign_item_fn(ccx, abis, &path, foreign_item);
353+
}
354+
}
355+
_ => ()
356+
}
357+
334358
let lname = link_name(ccx, foreign_item);
335359
ccx.item_symbols.insert(foreign_item.id, lname.to_owned());
336360
}
@@ -701,7 +725,7 @@ pub fn link_name(ccx: &CrateContext, i: @ast::foreign_item) -> @str {
701725
}
702726
}
703727

704-
fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig)
728+
fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig, arg_tys: &[ty::t])
705729
-> LlvmSignature {
706730
/*!
707731
* The ForeignSignature is the LLVM types of the arguments/return type
@@ -711,7 +735,7 @@ fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig)
711735
* values by pointer like we do.
712736
*/
713737

714-
let llarg_tys = fn_sig.inputs.map(|&arg| type_of(ccx, arg));
738+
let llarg_tys = arg_tys.map(|&arg| type_of(ccx, arg));
715739
let llret_ty = type_of::type_of(ccx, fn_sig.output);
716740
LlvmSignature {
717741
llarg_tys: llarg_tys,
@@ -731,7 +755,7 @@ fn foreign_types_for_fn_ty(ccx: &mut CrateContext,
731755
ty::ty_bare_fn(ref fn_ty) => fn_ty.sig.clone(),
732756
_ => ccx.sess.bug("foreign_types_for_fn_ty called on non-function type")
733757
};
734-
let llsig = foreign_signature(ccx, &fn_sig);
758+
let llsig = foreign_signature(ccx, &fn_sig, fn_sig.inputs);
735759
let ret_def = !ty::type_is_voidish(ccx.tcx, fn_sig.output);
736760
let fn_ty = cabi::compute_abi_info(ccx,
737761
llsig.llarg_tys,
@@ -790,7 +814,11 @@ fn lltype_for_fn_from_foreign_types(tys: &ForeignTypes) -> Type {
790814
llargument_tys.push(llarg_ty);
791815
}
792816

793-
Type::func(llargument_tys, &llreturn_ty)
817+
if tys.fn_sig.variadic {
818+
Type::variadic_func(llargument_tys, &llreturn_ty)
819+
} else {
820+
Type::func(llargument_tys, &llreturn_ty)
821+
}
794822
}
795823

796824
pub fn lltype_for_foreign_fn(ccx: &mut CrateContext, ty: ty::t) -> Type {

branches/try2/src/librustc/middle/trans/intrinsic.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,11 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
285285
let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty);
286286
Ret(bcx, td);
287287
}
288+
"type_id" => {
289+
let hash = ty::hash_crate_independent(ccx.tcx, substs.tys[0],
290+
ccx.link_meta.extras_hash);
291+
Ret(bcx, C_i64(hash as i64))
292+
}
288293
"init" => {
289294
let tp_ty = substs.tys[0];
290295
let lltp_ty = type_of::type_of(ccx, tp_ty);

branches/try2/src/librustc/middle/trans/reflect.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ impl Reflector {
375375
self.visit("fn_input", extra);
376376
}
377377
let extra = ~[self.c_uint(retval),
378+
self.c_bool(sig.variadic),
378379
self.c_tydesc(sig.output)];
379380
self.visit("fn_output", extra);
380381
}

branches/try2/src/librustc/middle/trans/type_.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ impl Type {
154154
args.len() as c_uint, False))
155155
}
156156

157+
pub fn variadic_func(args: &[Type], ret: &Type) -> Type {
158+
let vec : &[TypeRef] = unsafe { cast::transmute(args) };
159+
ty!(llvm::LLVMFunctionType(ret.to_ref(), vec::raw::to_ptr(vec),
160+
args.len() as c_uint, True))
161+
}
162+
157163
pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> Type {
158164
Type::struct_([fn_ty.ptr_to(), Type::opaque_cbox_ptr(cx)], false)
159165
}

0 commit comments

Comments
 (0)