@@ -950,7 +950,7 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
950
950
ty:: ty_class ( did, tps) {
951
951
// a class is like a record type
952
952
let mut i: int = 0 ;
953
- for vec:: each( ty:: class_items_as_fields( cx. tcx( ) , did) ) { |fld|
953
+ for vec:: each( ty:: class_items_as_fields( cx. tcx( ) , did, tps ) ) { |fld|
954
954
let llfld_a = GEPi ( cx, av, [ 0 , i] ) ;
955
955
cx = f ( cx, llfld_a, fld. mt . ty ) ;
956
956
i += 1 ;
@@ -1983,8 +1983,13 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
1983
1983
set_inline_hint ( lldecl) ;
1984
1984
trans_res_ctor ( ccx, pt, decl, fn_id. node , psubsts, lldecl) ;
1985
1985
}
1986
- ast:: item_class ( _, _, ctor) {
1987
- ccx. sess . unimpl ( "monomorphic class constructor" ) ;
1986
+ ast:: item_class ( tps, _, ctor) {
1987
+ set_inline_hint_if_appr ( i. attrs , lldecl) ;
1988
+ let tp_tys: [ ty:: t ] = ty:: ty_params_to_tys ( ccx. tcx , tps) ;
1989
+ trans_class_ctor ( ccx, pt, ctor. node . dec , ctor. node . body , lldecl,
1990
+ option:: get_or_default ( psubsts,
1991
+ { tys: tp_tys, vtables: none, bounds: @[ ] } ) ,
1992
+ fn_id. node , i. id , ctor. span ) ;
1988
1993
}
1989
1994
}
1990
1995
}
@@ -2238,7 +2243,8 @@ fn trans_rec_field_inner(bcx: block, val: ValueRef, ty: ty::t,
2238
2243
field : ast:: ident , sp : span ) -> lval_result {
2239
2244
let fields = alt ty:: get ( ty) . struct {
2240
2245
ty:: ty_rec ( fs) { fs }
2241
- ty:: ty_class ( did, _) { ty:: class_items_as_fields ( bcx. tcx ( ) , did) }
2246
+ ty:: ty_class ( did, ts) {
2247
+ ty:: class_items_as_fields ( bcx. tcx ( ) , did, ts) }
2242
2248
// Constraint?
2243
2249
_ { bcx. tcx ( ) . sess . span_bug ( sp, "trans_rec_field:\
2244
2250
base expr has non-record type") ; }
@@ -4255,6 +4261,61 @@ fn trans_const(ccx: @crate_ctxt, e: @ast::expr, id: ast::node_id) {
4255
4261
llvm:: LLVMSetGlobalConstant ( g, True ) ;
4256
4262
}
4257
4263
4264
+ fn trans_class_ctor ( ccx : @crate_ctxt , path : path , decl : ast:: fn_decl ,
4265
+ body : ast:: blk , llctor_decl : ValueRef ,
4266
+ psubsts : param_substs , ctor_id : ast:: node_id ,
4267
+ parent_id : ast:: node_id , sp : span ) {
4268
+ // Add ctor to the ctor map
4269
+ ccx. class_ctors . insert ( ctor_id, parent_id) ;
4270
+ // Translate the ctor
4271
+
4272
+ // Set up the type for the result of the ctor
4273
+ // kludgy -- this wouldn't be necessary if the typechecker
4274
+ // special-cased constructors, then we could just look up
4275
+ // the ctor's return type.
4276
+ let rslt_ty = ty:: mk_class ( ccx. tcx , local_def ( parent_id) ,
4277
+ psubsts. tys ) ;
4278
+ // Make the fn context
4279
+ let fcx = new_fn_ctxt_w_id ( ccx, path, llctor_decl, ctor_id,
4280
+ some ( psubsts) , some ( sp) ) ;
4281
+ // FIXME: need to substitute into the fn arg types too?
4282
+ create_llargs_for_fn_args ( fcx, no_self, decl. inputs ) ;
4283
+ let mut bcx_top = top_scope_block ( fcx, some ( sp) ) ;
4284
+ let lltop = bcx_top. llbb ;
4285
+ bcx_top = copy_args_to_allocas ( fcx, bcx_top, decl. inputs ,
4286
+ ty:: ty_fn_args ( node_id_type ( bcx_top, ctor_id) ) ) ;
4287
+
4288
+ // We *don't* want self to be passed to the ctor -- that
4289
+ // wouldn't make sense
4290
+ // So we initialize it here
4291
+ let selfptr = alloc_ty ( bcx_top, rslt_ty) ;
4292
+ // initialize fields to zero
4293
+ let fields = ty:: class_items_as_fields ( bcx_top. tcx ( ) ,
4294
+ local_def ( parent_id) ,
4295
+ psubsts. tys ) ;
4296
+ let mut bcx = bcx_top;
4297
+ // Initialize fields to zero so init assignments can validly
4298
+ // drop their LHS
4299
+ for field in fields {
4300
+ let ix = field_idx_strict ( bcx. tcx ( ) , sp, field. ident , fields) ;
4301
+ bcx = zero_alloca ( bcx, GEPi ( bcx, selfptr, [ 0 , ix] ) ,
4302
+ field. mt . ty ) ;
4303
+ }
4304
+
4305
+ // note we don't want to take *or* drop self.
4306
+ fcx. llself = some ( { v: selfptr, t: rslt_ty} ) ;
4307
+
4308
+ // Translate the body of the ctor
4309
+ bcx = trans_block ( bcx_top, body, ignore) ;
4310
+ let lval_res = { bcx: bcx, val: selfptr, kind: owned} ;
4311
+ // Generate the return expression
4312
+ bcx = store_temp_expr ( bcx, INIT , fcx. llretptr , lval_res,
4313
+ rslt_ty, true ) ;
4314
+ cleanup_and_leave ( bcx, none, some ( fcx. llreturn ) ) ;
4315
+ Unreachable ( bcx) ;
4316
+ finish_fn ( fcx, lltop) ;
4317
+ }
4318
+
4258
4319
fn trans_item ( ccx : @crate_ctxt , item : ast:: item ) {
4259
4320
let _icx = ccx. insn_ctxt ( "trans_item" ) ;
4260
4321
let path = alt check ccx. tcx . items . get ( item. id ) {
@@ -4322,62 +4383,15 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
4322
4383
native:: trans_native_mod ( ccx, native_mod, abi) ;
4323
4384
}
4324
4385
ast:: item_class ( tps, items, ctor) {
4325
- // FIXME factor our ctor translation, call from monomorphic_fn
4326
- let llctor_decl = get_item_val ( ccx, ctor. node . id ) ;
4327
- // Add ctor to the ctor map
4328
- ccx. class_ctors . insert ( ctor. node . id , item. id ) ;
4329
- // Translate the ctor
4330
-
4331
- // Set up the type for the result of the ctor
4332
- // kludgy -- this wouldn't be necessary if the typechecker
4333
- // special-cased constructors, then we could just look up
4334
- // the ctor's return type.
4335
- let ty_args = vec:: from_fn ( tps. len ( ) , { |i|
4336
- ty:: mk_param ( ccx. tcx , i, local_def ( tps[ i] . id ) )
4337
- } ) ;
4338
- let rslt_ty = ty:: mk_class ( ccx. tcx ,
4339
- local_def ( item. id ) ,
4340
- ty_args) ;
4341
-
4342
- // Make the fn context
4343
- let fcx = new_fn_ctxt_w_id ( ccx, * path, llctor_decl, ctor. node . id ,
4344
- // substs?
4345
- none, some ( ctor. span ) ) ;
4346
- create_llargs_for_fn_args ( fcx, no_self, ctor. node . dec . inputs ) ;
4347
- let mut bcx_top = top_scope_block ( fcx, some ( ctor. span ) ) ;
4348
- let lltop = bcx_top. llbb ;
4349
- bcx_top = copy_args_to_allocas ( fcx, bcx_top, ctor. node . dec . inputs ,
4350
- ty:: ty_fn_args ( node_id_type ( bcx_top, ctor. node . id ) ) ) ;
4351
-
4352
- // We *don't* want self to be passed to the ctor -- that
4353
- // wouldn't make sense
4354
- // So we initialize it here
4355
- let selfptr = alloc_ty ( bcx_top, rslt_ty) ;
4356
- // initialize fields to zero
4357
- let fields = ty:: class_items_as_fields ( bcx_top. tcx ( ) ,
4358
- local_def ( item. id ) ) ;
4359
- let mut bcx = bcx_top;
4360
- // Initialize fields to zero so init assignments can validly
4361
- // drop their LHS
4362
- for field in fields {
4363
- let ix = field_idx_strict ( bcx. tcx ( ) , ctor. span , field. ident ,
4364
- fields) ;
4365
- bcx = zero_alloca ( bcx, GEPi ( bcx, selfptr, [ 0 , ix] ) ,
4366
- field. mt . ty ) ;
4386
+ if tps. len ( ) == 0 u {
4387
+ let psubsts = { tys: ty:: ty_params_to_tys ( ccx. tcx , tps) ,
4388
+ vtables: none,
4389
+ bounds: @[ ] } ;
4390
+ trans_class_ctor ( ccx, * path, ctor. node . dec , ctor. node . body ,
4391
+ get_item_val ( ccx, ctor. node . id ) , psubsts,
4392
+ ctor. node . id , item. id , ctor. span ) ;
4367
4393
}
4368
-
4369
- // note we don't want to take *or* drop self.
4370
- fcx. llself = some ( { v: selfptr, t: rslt_ty} ) ;
4371
-
4372
- // Translate the body of the ctor
4373
- bcx = trans_block ( bcx_top, ctor. node . body , ignore) ;
4374
- let lval_res = { bcx: bcx, val: selfptr, kind: owned} ;
4375
- // Generate the return expression
4376
- bcx = store_temp_expr ( bcx, INIT , fcx. llretptr , lval_res,
4377
- rslt_ty, true ) ;
4378
- cleanup_and_leave ( bcx, none, some ( fcx. llreturn ) ) ;
4379
- Unreachable ( bcx) ;
4380
- finish_fn ( fcx, lltop) ;
4394
+ // If there are ty params, the ctor will get monomorphized
4381
4395
4382
4396
// Translate methods
4383
4397
let ( _, ms) = ast_util:: split_class_items ( items) ;
0 commit comments