@@ -22,7 +22,7 @@ use abi;
22
22
use value:: Value ;
23
23
24
24
use llvm;
25
- use llvm:: debuginfo:: { DIType , DIFile , DIScope , DIDescriptor ,
25
+ use llvm:: debuginfo:: { DIArray , DIType , DIFile , DIScope , DIDescriptor ,
26
26
DICompositeType , DILexicalBlock , DIFlags } ;
27
27
use llvm_util;
28
28
@@ -35,12 +35,14 @@ use rustc_data_structures::fingerprint::Fingerprint;
35
35
use rustc:: ty:: Instance ;
36
36
use common:: CodegenCx ;
37
37
use rustc:: ty:: { self , AdtKind , ParamEnv , Ty , TyCtxt } ;
38
- use rustc:: ty:: layout:: { self , Align , HasDataLayout , Integer , IntegerExt , LayoutOf ,
38
+ use rustc:: ty:: layout:: { self , Align , Integer , IntegerExt , LayoutOf ,
39
39
PrimitiveExt , Size , TyLayout } ;
40
+ use rustc:: ty:: subst:: UnpackedKind ;
40
41
use rustc:: session:: config;
41
42
use rustc:: util:: nodemap:: FxHashMap ;
42
43
use rustc_fs_util:: path_to_c_string;
43
44
use rustc_data_structures:: small_c_str:: SmallCStr ;
45
+ use rustc_target:: abi:: HasDataLayout ;
44
46
45
47
use libc:: { c_uint, c_longlong} ;
46
48
use std:: ffi:: CString ;
@@ -273,6 +275,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
273
275
274
276
// ... and attach them to the stub to complete it.
275
277
set_members_of_composite_type ( cx,
278
+ unfinished_type,
276
279
member_holding_stub,
277
280
member_descriptions) ;
278
281
return MetadataCreationResult :: new ( metadata_stub, true ) ;
@@ -1214,6 +1217,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1214
1217
member_description_factory. create_member_descriptions ( cx) ;
1215
1218
1216
1219
set_members_of_composite_type ( cx,
1220
+ self . enum_type ,
1217
1221
variant_type_metadata,
1218
1222
member_descriptions) ;
1219
1223
vec ! [
@@ -1254,6 +1258,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1254
1258
. create_member_descriptions ( cx) ;
1255
1259
1256
1260
set_members_of_composite_type ( cx,
1261
+ self . enum_type ,
1257
1262
variant_type_metadata,
1258
1263
member_descriptions) ;
1259
1264
MemberDescription {
@@ -1295,6 +1300,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1295
1300
member_description_factory. create_member_descriptions ( cx) ;
1296
1301
1297
1302
set_members_of_composite_type ( cx,
1303
+ self . enum_type ,
1298
1304
variant_type_metadata,
1299
1305
variant_member_descriptions) ;
1300
1306
@@ -1354,6 +1360,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1354
1360
. create_member_descriptions ( cx) ;
1355
1361
1356
1362
set_members_of_composite_type ( cx,
1363
+ self . enum_type ,
1357
1364
variant_type_metadata,
1358
1365
member_descriptions) ;
1359
1366
@@ -1765,13 +1772,15 @@ fn composite_type_metadata(
1765
1772
containing_scope) ;
1766
1773
// ... and immediately create and add the member descriptions.
1767
1774
set_members_of_composite_type ( cx,
1775
+ composite_type,
1768
1776
composite_type_metadata,
1769
1777
member_descriptions) ;
1770
1778
1771
1779
composite_type_metadata
1772
1780
}
1773
1781
1774
- fn set_members_of_composite_type ( cx : & CodegenCx < ' ll , ' _ > ,
1782
+ fn set_members_of_composite_type ( cx : & CodegenCx < ' ll , ' tcx > ,
1783
+ composite_type : Ty < ' tcx > ,
1775
1784
composite_type_metadata : & ' ll DICompositeType ,
1776
1785
member_descriptions : Vec < MemberDescription < ' ll > > ) {
1777
1786
// In some rare cases LLVM metadata uniquing would lead to an existing type
@@ -1815,10 +1824,57 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
1815
1824
} )
1816
1825
. collect ( ) ;
1817
1826
1827
+ let type_params = compute_type_parameters ( cx, composite_type) ;
1818
1828
unsafe {
1819
1829
let type_array = create_DIArray ( DIB ( cx) , & member_metadata[ ..] ) ;
1820
- llvm:: LLVMRustDICompositeTypeSetTypeArray (
1821
- DIB ( cx) , composite_type_metadata, type_array) ;
1830
+ llvm:: LLVMRustDICompositeTypeReplaceArrays (
1831
+ DIB ( cx) , composite_type_metadata, Some ( type_array) , type_params) ;
1832
+ }
1833
+ }
1834
+
1835
+ // Compute the type parameters for a type, if any, for the given
1836
+ // metadata.
1837
+ fn compute_type_parameters ( cx : & CodegenCx < ' ll , ' tcx > , ty : Ty < ' tcx > ) -> Option < & ' ll DIArray > {
1838
+ if let ty:: Adt ( def, substs) = ty. sty {
1839
+ if !substs. types ( ) . next ( ) . is_none ( ) {
1840
+ let generics = cx. tcx . generics_of ( def. did ) ;
1841
+ let names = get_parameter_names ( cx, generics) ;
1842
+ let template_params: Vec < _ > = substs. iter ( ) . zip ( names) . filter_map ( |( kind, name) | {
1843
+ if let UnpackedKind :: Type ( ty) = kind. unpack ( ) {
1844
+ let actual_type = cx. tcx . normalize_erasing_regions ( ParamEnv :: reveal_all ( ) , ty) ;
1845
+ let actual_type_metadata =
1846
+ type_metadata ( cx, actual_type, syntax_pos:: DUMMY_SP ) ;
1847
+ let name = SmallCStr :: new ( & name. as_str ( ) ) ;
1848
+ Some ( unsafe {
1849
+
1850
+ Some ( llvm:: LLVMRustDIBuilderCreateTemplateTypeParameter (
1851
+ DIB ( cx) ,
1852
+ None ,
1853
+ name. as_ptr ( ) ,
1854
+ actual_type_metadata,
1855
+ unknown_file_metadata ( cx) ,
1856
+ 0 ,
1857
+ 0 ,
1858
+ ) )
1859
+ } )
1860
+ } else {
1861
+ None
1862
+ }
1863
+ } ) . collect ( ) ;
1864
+
1865
+ return Some ( create_DIArray ( DIB ( cx) , & template_params[ ..] ) ) ;
1866
+ }
1867
+ }
1868
+ return Some ( create_DIArray ( DIB ( cx) , & [ ] ) ) ;
1869
+
1870
+ fn get_parameter_names ( cx : & CodegenCx ,
1871
+ generics : & ty:: Generics )
1872
+ -> Vec < InternedString > {
1873
+ let mut names = generics. parent . map_or ( vec ! [ ] , |def_id| {
1874
+ get_parameter_names ( cx, cx. tcx . generics_of ( def_id) )
1875
+ } ) ;
1876
+ names. extend ( generics. params . iter ( ) . map ( |param| param. name ) ) ;
1877
+ names
1822
1878
}
1823
1879
}
1824
1880
0 commit comments