@@ -49,6 +49,7 @@ use lib::llvm::debuginfo::*;
49
49
use middle:: trans:: common:: * ;
50
50
use middle:: trans:: machine;
51
51
use middle:: trans:: type_of;
52
+ use middle:: trans:: type_:: Type ;
52
53
use middle:: trans;
53
54
use middle:: ty;
54
55
use util:: ppaux:: ty_to_str;
@@ -65,6 +66,8 @@ use syntax::codemap::span;
65
66
use syntax:: { ast, codemap, ast_util, ast_map} ;
66
67
use syntax:: parse:: token;
67
68
69
+
70
+
68
71
static DW_LANG_RUST : int = 0x9000 ;
69
72
70
73
static AutoVariableTag : int = 256 ;
@@ -594,17 +597,102 @@ fn create_struct(cx: &mut CrateContext, struct_type: ty::t, fields: ~[ty::field]
594
597
-> DICompositeType {
595
598
debug ! ( "create_struct: %?" , ty:: get( struct_type) ) ;
596
599
600
+ let struct_name = ty_to_str ( cx. tcx , struct_type) ;
601
+ let struct_llvm_type = type_of:: type_of ( cx, struct_type) ;
602
+
603
+ let field_llvm_types = fields. map ( |field| type_of:: type_of ( cx, field. mt . ty ) ) ;
604
+ let field_names = fields. map ( |field| cx. sess . str_of ( field. ident ) . to_owned ( ) ) ;
605
+ let field_types_metadata = fields. map ( |field| create_ty ( cx, field. mt . ty , span) ) ;
606
+
607
+ return create_composite_type (
608
+ cx,
609
+ struct_llvm_type,
610
+ struct_name,
611
+ field_llvm_types,
612
+ field_names,
613
+ field_types_metadata,
614
+ span) ;
615
+ }
616
+
617
+ fn create_tuple ( cx : & mut CrateContext ,
618
+ tuple_type : ty:: t ,
619
+ component_types : & [ ty:: t ] ,
620
+ span : span )
621
+ -> DICompositeType {
622
+
623
+ let tuple_name = ( cx. sess . str_of ( ( dbg_cx ( cx) . names ) ( "tuple" ) ) ) . to_owned ( ) ;
624
+ let tuple_llvm_type = type_of:: type_of ( cx, tuple_type) ;
625
+ // Create a vec of empty strings. A vec::build_n() function would be nice for this.
626
+ let mut component_names : ~[ ~str ] = vec:: with_capacity ( component_types. len ( ) ) ;
627
+ component_names. grow_fn ( component_types. len ( ) , |_| ~"") ;
628
+
629
+ let component_llvm_types = component_types. map ( |it| type_of:: type_of ( cx, * it) ) ;
630
+ let component_types_metadata = component_types. map ( |it| create_ty ( cx, * it, span) ) ;
631
+
632
+ return create_composite_type (
633
+ cx,
634
+ tuple_llvm_type,
635
+ tuple_name,
636
+ component_llvm_types,
637
+ component_names,
638
+ component_types_metadata,
639
+ span) ;
640
+ }
641
+
642
+ fn create_composite_type ( cx : & mut CrateContext ,
643
+ composite_llvm_type : Type ,
644
+ composite_type_name : & str ,
645
+ member_llvm_types : & [ Type ] ,
646
+ member_names : & [ ~str ] ,
647
+ member_type_metadata : & [ DIType ] ,
648
+ span : span )
649
+ -> DICompositeType {
650
+
597
651
let loc = span_start ( cx, span) ;
598
- let file_md = create_file ( cx, loc. file . name ) ;
652
+ let file_metadata = create_file ( cx, loc. file . name ) ;
653
+
654
+ let composite_size = machine:: llsize_of_alloc ( cx, composite_llvm_type) ;
655
+ let composite_align = machine:: llalign_of_min ( cx, composite_llvm_type) ;
656
+
657
+ let member_metadata = create_DIArray (
658
+ DIB ( cx) ,
659
+ // transform the ty::t array of components into an array of DIEs
660
+ do vec:: mapi ( member_llvm_types) |i, member_llvm_type| {
661
+ let member_size = machine:: llsize_of_alloc ( cx, * member_llvm_type) ;
662
+ let member_align = machine:: llalign_of_min ( cx, * member_llvm_type) ;
663
+ let member_offset = machine:: llelement_offset ( cx, composite_llvm_type, i) ;
664
+ let member_name : & str = member_names[ i] ;
665
+
666
+ do member_name. as_c_str |member_name| { unsafe {
667
+ llvm:: LLVMDIBuilderCreateMemberType (
668
+ DIB ( cx) ,
669
+ file_metadata,
670
+ member_name,
671
+ file_metadata,
672
+ loc. line as c_uint ,
673
+ bytes_to_bits ( member_size) ,
674
+ bytes_to_bits ( member_align) ,
675
+ bytes_to_bits ( member_offset) ,
676
+ 0 ,
677
+ member_type_metadata[ i] )
678
+ } }
679
+ } ) ;
599
680
600
- let mut scx = StructContext :: new ( cx, ty_to_str ( cx. tcx , struct_type) , file_md, loc. line ) ;
601
- for fields. iter( ) . advance |field| {
602
- let field_t = field. mt. ty;
603
- let ty_md = create_ty( cx, field_t, span) ;
604
- let ( size, align) = size_and_align_of ( cx, field_t) ;
605
- scx. add_member ( cx. sess . str_of ( field. ident ) , loc. line , size, align, ty_md) ;
606
- }
607
- return scx. finalize ( ) ;
681
+ return do composite_type_name. as_c_str |name| { unsafe {
682
+ llvm:: LLVMDIBuilderCreateStructType (
683
+ DIB ( cx) ,
684
+ file_metadata,
685
+ name,
686
+ file_metadata,
687
+ loc. line as c_uint ,
688
+ bytes_to_bits ( composite_size) ,
689
+ bytes_to_bits ( composite_align) ,
690
+ 0 ,
691
+ ptr:: null ( ) ,
692
+ member_metadata,
693
+ 0 ,
694
+ ptr:: null ( ) )
695
+ } } ;
608
696
}
609
697
610
698
// returns (void* type as a ValueRef, size in bytes, align in bytes)
@@ -639,30 +727,83 @@ fn create_tuple(cx: &mut CrateContext, tuple_type: ty::t, elements: &[ty::t], sp
639
727
return scx. finalize ( ) ;
640
728
}
641
729
642
- fn create_boxed_type ( cx : & mut CrateContext , contents : ty:: t ,
643
- span : span , boxed : DIType ) -> DICompositeType {
644
- debug ! ( "create_boxed_type: %?" , ty:: get( contents) ) ;
645
-
646
- let loc = span_start ( cx, span) ;
647
- let file_md = create_file ( cx, loc. file . name ) ;
648
- let int_t = ty:: mk_int ( ) ;
649
- let refcount_type = create_basic_type ( cx, int_t, span) ;
650
- let name = ty_to_str ( cx. tcx , contents) ;
651
-
652
- let mut scx = StructContext :: new ( cx, fmt ! ( "box<%s>" , name) , file_md, 0 ) ;
653
- scx. add_member ( "refcnt" , 0 , sys:: size_of :: < uint > ( ) ,
654
- sys:: min_align_of :: < uint > ( ) , refcount_type) ;
655
- // the tydesc and other pointers should be irrelevant to the
656
- // debugger, so treat them as void* types
657
- let ( vp, vpsize, vpalign) = voidptr ( cx) ;
658
- scx. add_member ( "tydesc" , 0 , vpsize, vpalign, vp) ;
659
- scx. add_member ( "prev" , 0 , vpsize, vpalign, vp) ;
660
- scx. add_member ( "next" , 0 , vpsize, vpalign, vp) ;
661
- let ( size, align) = size_and_align_of ( cx, contents) ;
662
- scx. add_member ( "boxed" , 0 , size, align, boxed) ;
663
- return scx. finalize ( ) ;
730
+ fn create_boxed_type ( cx : & mut CrateContext ,
731
+ content_type : ty:: t ,
732
+ span : span )
733
+ -> DICompositeType {
734
+
735
+ debug ! ( "create_boxed_type: %?" , ty:: get( content_type) ) ;
736
+
737
+ let content_llvm_type = type_of:: type_of ( cx, content_type) ;
738
+ let content_type_metadata = create_ty ( cx, content_type, span) ;
739
+
740
+ let box_llvm_type = Type :: box ( cx, & content_llvm_type) ;
741
+ let member_llvm_types = box_llvm_type. field_types ( ) ;
742
+ let member_names = [ ~"refcnt", ~"tydesc", ~"prev", ~"next", ~"val"] ;
743
+
744
+ assert ! ( box_layout_is_as_expected( cx, member_llvm_types, content_llvm_type) ) ;
745
+
746
+ let int_type = ty:: mk_int ( ) ;
747
+ let nil_pointer_type = ty:: mk_nil_ptr ( cx. tcx ) ;
748
+
749
+ let member_types_metadata = [
750
+ create_ty ( cx, int_type, span) ,
751
+ create_ty ( cx, nil_pointer_type, span) ,
752
+ create_ty ( cx, nil_pointer_type, span) ,
753
+ create_ty ( cx, nil_pointer_type, span) ,
754
+ content_type_metadata
755
+ ] ;
756
+
757
+ return create_composite_type (
758
+ cx,
759
+ box_llvm_type,
760
+ "box name" ,
761
+ member_llvm_types,
762
+ member_names,
763
+ member_types_metadata,
764
+ span) ;
765
+
766
+ fn box_layout_is_as_expected ( cx : & CrateContext ,
767
+ member_types : & [ Type ] ,
768
+ content_type : Type )
769
+ -> bool {
770
+ return member_types[ 0 ] == cx. int_type
771
+ && member_types[ 1 ] == cx. tydesc_type . ptr_to ( )
772
+ && member_types[ 2 ] == Type :: i8 ( ) . ptr_to ( )
773
+ && member_types[ 3 ] == Type :: i8 ( ) . ptr_to ( )
774
+ && member_types[ 4 ] == content_type;
775
+ }
664
776
}
665
777
778
+ // fn create_boxed_type(cx: &mut CrateContext,
779
+ // contents: ty::t,
780
+ // span: span,
781
+ // boxed: DIType)
782
+ // -> DICompositeType {
783
+
784
+ // debug!("create_boxed_type: %?", ty::get(contents));
785
+
786
+ // let loc = span_start(cx, span);
787
+ // let file_md = create_file(cx, loc.file.name);
788
+ // let int_t = ty::mk_int();
789
+ // let refcount_type = create_basic_type(cx, int_t, span);
790
+ // let name = ty_to_str(cx.tcx, contents);
791
+
792
+ // let mut scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0);
793
+ // scx.add_member("refcnt", 0, sys::size_of::<uint>(),
794
+ // sys::min_align_of::<uint>(), refcount_type);
795
+ // // the tydesc and other pointers should be irrelevant to the
796
+ // // debugger, so treat them as void* types
797
+ // let (vp, vpsize, vpalign) = voidptr(cx);
798
+ // scx.add_member("tydesc", 0, vpsize, vpalign, vp);
799
+ // scx.add_member("prev", 0, vpsize, vpalign, vp);
800
+ // scx.add_member("next", 0, vpsize, vpalign, vp);
801
+ // let (size, align) = size_and_align_of(cx, contents);
802
+ // scx.add_member("val", 0, size, align, boxed);
803
+ // return scx.finalize();
804
+ // }
805
+
806
+
666
807
fn create_fixed_vec ( cx : & mut CrateContext , _vec_t : ty:: t , elem_t : ty:: t ,
667
808
len : uint , span : span ) -> DIType {
668
809
debug ! ( "create_fixed_vec: %?" , ty:: get( _vec_t) ) ;
@@ -840,9 +981,8 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
840
981
create_unimpl_ty ( cx, t)
841
982
}
842
983
ty:: ty_box( ref mt) | ty:: ty_uniq( ref mt) => {
843
- let boxed = create_ty ( cx, mt. ty , span) ;
844
- let box_md = create_boxed_type ( cx, mt. ty , span, boxed) ;
845
- create_pointer_type ( cx, t, span, box_md)
984
+ let box_metadata = create_boxed_type ( cx, mt. ty , span) ;
985
+ create_pointer_type ( cx, t, span, box_metadata)
846
986
} ,
847
987
ty:: ty_evec( ref mt, ref vstore) => {
848
988
match * vstore {
@@ -858,10 +998,7 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
858
998
}
859
999
}
860
1000
} ,
861
- ty:: ty_ptr( ref mt) => {
862
- let pointee = create_ty ( cx, mt. ty , span) ;
863
- create_pointer_type ( cx, t, span, pointee)
864
- } ,
1001
+ ty:: ty_ptr( ref mt) |
865
1002
ty:: ty_rptr( _, ref mt) => {
866
1003
let pointee = create_ty ( cx, mt. ty , span) ;
867
1004
create_pointer_type ( cx, t, span, pointee)
0 commit comments