@@ -501,9 +501,9 @@ fn create_struct(cx: &mut CrateContext,
501
501
fields : ~[ ty:: field ] ,
502
502
span : span )
503
503
-> DICompositeType {
504
- debug ! ( "create_struct: %?" , ty:: get( struct_type) ) ;
505
-
506
504
let struct_name = ty_to_str ( cx. tcx , struct_type) ;
505
+ debug ! ( "create_struct: %s" , struct_name) ;
506
+
507
507
let struct_llvm_type = type_of:: type_of ( cx, struct_type) ;
508
508
509
509
let field_llvm_types = fields. map ( |field| type_of:: type_of ( cx, field. mt . ty ) ) ;
@@ -526,7 +526,7 @@ fn create_tuple(cx: &mut CrateContext,
526
526
span : span )
527
527
-> DICompositeType {
528
528
529
- let tuple_name = "tuple" ; // this should have a better name
529
+ let tuple_name = ty_to_str ( cx . tcx , tuple_type ) ;
530
530
let tuple_llvm_type = type_of:: type_of ( cx, tuple_type) ;
531
531
// Create a vec of empty strings. A vec::build_n() function would be nice for this.
532
532
let mut component_names : ~[ ~str ] = vec:: with_capacity ( component_types. len ( ) ) ;
@@ -548,61 +548,117 @@ fn create_tuple(cx: &mut CrateContext,
548
548
fn create_enum_md ( cx : & mut CrateContext ,
549
549
enum_type : ty:: t ,
550
550
enum_def_id : ast:: def_id ,
551
- span : span ) -> DIType {
551
+ substs : & ty:: substs ,
552
+ span : span )
553
+ -> DIType {
552
554
553
555
let enum_name = ty_to_str ( cx. tcx , enum_type) ;
554
- let discriminator_llvm_type = Type :: enum_discrim ( cx) ;
555
- let discriminator_size = machine:: llsize_of_alloc ( cx, discriminator_llvm_type) ;
556
- let discriminator_align = machine:: llalign_of_min ( cx, discriminator_llvm_type) ;
557
-
558
- assert ! ( Type :: enum_discrim( cx) == cx. int_type) ;
559
- let discriminator_type_md = get_or_create_type ( cx, ty:: mk_int ( ) , span) ;
560
556
557
+ // For empty enums there is an early exit. Just describe it as an empty struct with the
558
+ // appropriate name
561
559
if ty:: type_is_empty ( cx. tcx , enum_type) {
562
- // XXX: This should not "rename" the type to nil
563
- return get_or_create_type ( cx, ty:: mk_nil ( ) , span) ;
560
+ return create_composite_type ( cx, Type :: nil ( ) , enum_name, & [ ] , & [ ] , & [ ] , span) ;
564
561
}
565
562
566
- if ty:: type_is_c_like_enum ( cx. tcx , enum_type) {
563
+ // Prepare some data (llvm type, size, align, ...) about the discriminant. This data will be
564
+ // needed in all of the following cases.
565
+ let discriminant_llvm_type = Type :: enum_discrim ( cx) ;
566
+ let discriminant_size = machine:: llsize_of_alloc ( cx, discriminant_llvm_type) ;
567
+ let discriminant_align = machine:: llalign_of_min ( cx, discriminant_llvm_type) ;
568
+ assert ! ( Type :: enum_discrim( cx) == cx. int_type) ;
569
+ let discriminant_type_md = get_or_create_type ( cx, ty:: mk_int ( ) , span) ;
570
+
571
+
572
+ let variants : & [ ty:: VariantInfo ] = * ty:: enum_variants ( cx. tcx , enum_def_id) ;
567
573
568
- let variants : & [ ty:: VariantInfo ] = * ty:: enum_variants ( cx. tcx , enum_def_id) ;
574
+ let enumerators : ~[ ( ~str , int ) ] = variants
575
+ . iter ( )
576
+ . transform ( |v| ( cx. sess . str_of ( v. name ) . to_owned ( ) , v. disr_val ) )
577
+ . collect ( ) ;
578
+
579
+ let enumerators_md : ~[ DIDescriptor ] =
580
+ do enumerators. iter ( ) . transform |& ( name, value) | {
581
+ do name. as_c_str |name| { unsafe {
582
+ llvm:: LLVMDIBuilderCreateEnumerator (
583
+ DIB ( cx) ,
584
+ name,
585
+ value as c_ulonglong )
586
+ } }
587
+ } . collect ( ) ;
569
588
570
- let enumerators : ~[ ( ~str , int ) ] = variants
571
- . iter ( )
572
- . transform ( |v| ( cx. sess . str_of ( v. name ) . to_owned ( ) , v. disr_val ) )
573
- . collect ( ) ;
589
+ let loc = span_start ( cx, span) ;
590
+ let file_metadata = get_or_create_file ( cx, loc. file . name ) ;
574
591
575
- let enumerators_md : ~[ DIDescriptor ] =
576
- do enumerators. iter ( ) . transform |& ( name, value) | {
577
- do name. as_c_str |name| { unsafe {
578
- llvm:: LLVMDIBuilderCreateEnumerator (
579
- DIB ( cx) ,
580
- name,
581
- value as c_ulonglong )
582
- } }
583
- } . collect ( ) ;
592
+ let discriminant_type_md = do enum_name. as_c_str |enum_name| { unsafe {
593
+ llvm:: LLVMDIBuilderCreateEnumerationType (
594
+ DIB ( cx) ,
595
+ file_metadata,
596
+ enum_name,
597
+ file_metadata,
598
+ loc. line as c_uint ,
599
+ bytes_to_bits ( discriminant_size) ,
600
+ bytes_to_bits ( discriminant_align) ,
601
+ create_DIArray ( DIB ( cx) , enumerators_md) ,
602
+ discriminant_type_md)
603
+ } } ;
584
604
585
- let loc = span_start ( cx, span) ;
586
- let file_metadata = get_or_create_file ( cx, loc. file . name ) ;
605
+ if ty:: type_is_c_like_enum ( cx. tcx , enum_type) {
606
+ return discriminant_type_md;
607
+ }
587
608
588
- return do enum_name. as_c_str |enum_name| { unsafe {
589
- llvm:: LLVMDIBuilderCreateEnumerationType (
609
+ let variants_md = do variants. map |& vi| {
610
+
611
+ let raw_types : & [ ty:: t ] = vi. args ;
612
+ let arg_types = do raw_types. map |& raw_type| { ty:: subst ( cx. tcx , substs, raw_type) } ;
613
+ let arg_llvm_types = ~[ discriminant_llvm_type] + do arg_types. map |& ty| { type_of:: type_of ( cx, ty) } ;
614
+ let arg_names = ~[ ~""] + arg_types. map ( |_| ~"") ;
615
+ let arg_md = ~[ discriminant_type_md] + do arg_types. map |& ty| { get_or_create_type ( cx, ty, span) } ;
616
+
617
+ let variant_llvm_type = Type :: struct_ ( arg_llvm_types, false ) ;
618
+ let variant_type_size = machine:: llsize_of_alloc ( cx, variant_llvm_type) ;
619
+ let variant_type_align = machine:: llalign_of_min ( cx, variant_llvm_type) ;
620
+
621
+ let variant_type_md = create_composite_type (
622
+ cx,
623
+ variant_llvm_type,
624
+ & "" ,
625
+ arg_llvm_types,
626
+ arg_names,
627
+ arg_md,
628
+ span) ;
629
+
630
+ do "" . as_c_str |name| { unsafe {
631
+ llvm:: LLVMDIBuilderCreateMemberType (
590
632
DIB ( cx) ,
591
633
file_metadata,
592
- enum_name ,
634
+ name ,
593
635
file_metadata,
594
636
loc. line as c_uint ,
595
- bytes_to_bits ( discriminator_size) ,
596
- bytes_to_bits ( discriminator_align) ,
597
- create_DIArray ( DIB ( cx) , enumerators_md) ,
598
- discriminator_type_md)
599
- } } ;
600
- }
601
-
602
- cx. sess . bug ( "" ) ;
603
- }
637
+ bytes_to_bits ( variant_type_size) ,
638
+ bytes_to_bits ( variant_type_align) ,
639
+ bytes_to_bits ( 0 ) ,
640
+ 0 ,
641
+ variant_type_md)
642
+ } }
643
+ } ;
604
644
645
+ let enum_llvm_type = type_of:: type_of ( cx, enum_type) ;
646
+ let enum_type_size = machine:: llsize_of_alloc ( cx, enum_llvm_type) ;
647
+ let enum_type_align = machine:: llalign_of_min ( cx, enum_llvm_type) ;
605
648
649
+ return do "" . as_c_str |enum_name| { unsafe { llvm:: LLVMDIBuilderCreateUnionType (
650
+ DIB ( cx) ,
651
+ file_metadata,
652
+ enum_name,
653
+ file_metadata,
654
+ loc. line as c_uint ,
655
+ bytes_to_bits ( enum_type_size) ,
656
+ bytes_to_bits ( enum_type_align) ,
657
+ 0 , // Flags
658
+ create_DIArray ( DIB ( cx) , variants_md) ,
659
+ 0 ) // RuntimeLang
660
+ } } ;
661
+ }
606
662
607
663
608
664
/// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
@@ -899,10 +955,8 @@ fn get_or_create_type(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
899
955
}
900
956
}
901
957
} ,
902
- ty:: ty_enum( def_id, ref _substs) => {
903
- //cx.sess.span_note(span, "debuginfo for enum NYI");
904
- //create_unimpl_ty(cx, t)
905
- create_enum_md ( cx, t, def_id, span)
958
+ ty:: ty_enum( def_id, ref substs) => {
959
+ create_enum_md ( cx, t, def_id, substs, span)
906
960
} ,
907
961
ty:: ty_box( ref mt) |
908
962
ty:: ty_uniq( ref mt) => {
0 commit comments