@@ -271,11 +271,11 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
271
271
let cx = fcx. ccx ;
272
272
273
273
let fnitem = cx. tcx . items . get_copy ( & fcx. id ) ;
274
- let ( ident, fn_decl, id) = match fnitem {
274
+ let ( ident, fn_decl, id, generics ) = match fnitem {
275
275
ast_map:: node_item( ref item, _) => {
276
276
match item. node {
277
- ast:: item_fn( ref fn_decl, _, _, _ , _) => {
278
- ( item. ident , fn_decl , item. id )
277
+ ast:: item_fn( ref fn_decl, _, _, ref generics , _) => {
278
+ ( item. ident , ty , item. id , Some ( generics ) )
279
279
}
280
280
_ => fcx. ccx . sess . span_bug ( item. span ,
281
281
"create_function_metadata: item bound to non-function" )
@@ -286,17 +286,21 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
286
286
decl : ref fn_decl,
287
287
id : id,
288
288
ident : ident,
289
+ generics : ref generics,
289
290
_
290
291
} ,
291
292
_,
292
293
_) => {
293
- ( ident, fn_decl, id)
294
+ ( ident, fn_decl, id, Some ( generics ) )
294
295
}
295
296
ast_map:: node_expr( ref expr) => {
296
297
match expr. node {
297
298
ast:: expr_fn_block( ref fn_decl, _) => {
298
299
let name = gensym_name ( "fn" ) ;
299
- ( name, fn_decl, expr. id )
300
+ ( name, fn_decl, expr. id ,
301
+ // This is not quite right. It should actually inherit the generics of the
302
+ // enclosing function.
303
+ None )
300
304
}
301
305
_ => fcx. ccx . sess . span_bug ( expr. span ,
302
306
"create_function_metadata: expected an expr_fn_block here" )
@@ -308,11 +312,12 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
308
312
decl : ref fn_decl,
309
313
id : id,
310
314
ident : ident,
315
+ generics : ref generics,
311
316
_
312
317
} ) ,
313
318
_,
314
319
_) => {
315
- ( ident, fn_decl, id)
320
+ ( ident, fn_decl, id, Some ( generics ) )
316
321
}
317
322
_ => fcx. ccx . sess . bug ( fmt ! ( "create_function_metadata: unexpected sort of node: %?" , fnitem) )
318
323
} ;
@@ -336,8 +341,18 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
336
341
337
342
let return_type_metadata = if cx. sess . opts . extra_debuginfo {
338
343
match fn_decl. output . node {
339
- ast:: ty_nil => ptr:: null ( ) ,
340
- _ => type_metadata ( cx, ty:: node_id_to_type ( cx. tcx , id) , fn_decl. output . span )
344
+ ast:: ty_nil => ptr:: null ( ) ,
345
+ _ => {
346
+ let return_type = ty:: node_id_to_type ( cx. tcx , id) ;
347
+ let return_type = match fcx. param_substs {
348
+ None => return_type,
349
+ Some ( substs) => {
350
+ ty:: subst_tps ( cx. tcx , substs. tys , substs. self_ty , return_type)
351
+ }
352
+ } ;
353
+
354
+ type_metadata ( cx, return_type, ret_ty. span )
355
+ }
341
356
}
342
357
} else {
343
358
ptr:: null ( )
@@ -350,6 +365,8 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
350
365
create_DIArray ( DIB ( cx) , [ return_type_metadata] ) )
351
366
} ;
352
367
368
+ let template_parameters: DIArray = get_template_parameters ( cx, fcx, generics, file_metadata, span) ;
369
+
353
370
let fn_metadata =
354
371
do cx. sess . str_of ( ident) . with_c_str |name| {
355
372
do cx. sess . str_of ( ident) . with_c_str |linkage| {
@@ -368,7 +385,7 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
368
385
FlagPrototyped as c_uint ,
369
386
cx. sess . opts . optimize != session:: No ,
370
387
fcx. llfn ,
371
- ptr :: null ( ) ,
388
+ template_parameters ,
372
389
ptr:: null ( ) )
373
390
}
374
391
} } ;
@@ -396,6 +413,68 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
396
413
397
414
dbg_cx ( cx) . created_functions . insert ( id, fn_metadata) ;
398
415
return fn_metadata;
416
+
417
+ fn get_template_parameters ( cx : & mut CrateContext ,
418
+ fcx : & FunctionContext ,
419
+ generics : Option < & ast:: Generics > ,
420
+ file_metadata : DIFile ,
421
+ span : span ) -> DIArray {
422
+ // Normalize cases
423
+ let generics = match generics {
424
+ Some ( generics_ref) if generics_ref. is_type_parameterized ( ) => Some ( generics_ref) ,
425
+ _ => None
426
+ } ;
427
+
428
+ match generics {
429
+ None => {
430
+ if ( fcx. param_substs . is_some ( ) ) {
431
+ cx. sess . span_bug ( span, "debuginfo::create_function_metadata() - \
432
+ Mismatch between ast::Generics and FunctionContext::param_substs 111") ;
433
+ }
434
+
435
+ return ptr:: null ( ) ;
436
+ }
437
+
438
+ Some ( generics) => {
439
+ let actual_types = match fcx. param_substs {
440
+ Some ( @param_substs { tys : ref actual_types, _} ) => {
441
+ actual_types
442
+ }
443
+ None => {
444
+ cx. sess . span_bug ( span, "debuginfo::create_function_metadata() - \
445
+ Mismatch between ast::Generics and FunctionContext::param_substs 222") ;
446
+ }
447
+ } ;
448
+
449
+ let template_params: ~[ DIDescriptor ] = do generics
450
+ . ty_params
451
+ . iter ( )
452
+ . enumerate ( )
453
+ . transform |( index, & ast:: TyParam { ident : ident, _ } ) | {
454
+
455
+ let actual_type = actual_types[ index] ;
456
+ let actual_type_metadata = type_metadata ( cx,
457
+ actual_type,
458
+ codemap:: dummy_sp ( ) ) ;
459
+
460
+ do cx. sess . str_of ( ident) . as_c_str |name| {
461
+ unsafe {
462
+ llvm:: LLVMDIBuilderCreateTemplateTypeParameter (
463
+ DIB ( cx) ,
464
+ file_metadata,
465
+ name,
466
+ actual_type_metadata,
467
+ ptr:: null ( ) ,
468
+ 0 ,
469
+ 0 )
470
+ }
471
+ }
472
+ } . collect ( ) ;
473
+
474
+ return create_DIArray ( DIB ( cx) , template_params) ;
475
+ }
476
+ }
477
+ }
399
478
}
400
479
401
480
0 commit comments