@@ -786,7 +786,10 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
786
786
usage_site_span) . finalize ( cx)
787
787
}
788
788
ty:: TyUnion ( ..) => {
789
- unimplemented ! ( ) ;
789
+ prepare_union_metadata ( cx,
790
+ t,
791
+ unique_type_id,
792
+ usage_site_span) . finalize ( cx)
790
793
}
791
794
ty:: TyTuple ( ref elements) => {
792
795
prepare_tuple_metadata ( cx,
@@ -1038,6 +1041,7 @@ enum MemberDescriptionFactory<'tcx> {
1038
1041
StructMDF ( StructMemberDescriptionFactory < ' tcx > ) ,
1039
1042
TupleMDF ( TupleMemberDescriptionFactory < ' tcx > ) ,
1040
1043
EnumMDF ( EnumMemberDescriptionFactory < ' tcx > ) ,
1044
+ UnionMDF ( UnionMemberDescriptionFactory < ' tcx > ) ,
1041
1045
VariantMDF ( VariantMemberDescriptionFactory < ' tcx > )
1042
1046
}
1043
1047
@@ -1054,6 +1058,9 @@ impl<'tcx> MemberDescriptionFactory<'tcx> {
1054
1058
EnumMDF ( ref this) => {
1055
1059
this. create_member_descriptions ( cx)
1056
1060
}
1061
+ UnionMDF ( ref this) => {
1062
+ this. create_member_descriptions ( cx)
1063
+ }
1057
1064
VariantMDF ( ref this) => {
1058
1065
this. create_member_descriptions ( cx)
1059
1066
}
@@ -1154,7 +1161,6 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1154
1161
)
1155
1162
}
1156
1163
1157
-
1158
1164
//=-----------------------------------------------------------------------------
1159
1165
// Tuples
1160
1166
//=-----------------------------------------------------------------------------
@@ -1209,6 +1215,66 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1209
1215
)
1210
1216
}
1211
1217
1218
+ //=-----------------------------------------------------------------------------
1219
+ // Unions
1220
+ //=-----------------------------------------------------------------------------
1221
+
1222
+ struct UnionMemberDescriptionFactory < ' tcx > {
1223
+ variant : ty:: VariantDef < ' tcx > ,
1224
+ substs : & ' tcx Substs < ' tcx > ,
1225
+ span : Span ,
1226
+ }
1227
+
1228
+ impl < ' tcx > UnionMemberDescriptionFactory < ' tcx > {
1229
+ fn create_member_descriptions < ' a > ( & self , cx : & CrateContext < ' a , ' tcx > )
1230
+ -> Vec < MemberDescription > {
1231
+ self . variant . fields . iter ( ) . map ( |field| {
1232
+ let fty = monomorphize:: field_ty ( cx. tcx ( ) , self . substs , field) ;
1233
+ MemberDescription {
1234
+ name : field. name . to_string ( ) ,
1235
+ llvm_type : type_of:: type_of ( cx, fty) ,
1236
+ type_metadata : type_metadata ( cx, fty, self . span ) ,
1237
+ offset : FixedMemberOffset { bytes : 0 } ,
1238
+ flags : FLAGS_NONE ,
1239
+ }
1240
+ } ) . collect ( )
1241
+ }
1242
+ }
1243
+
1244
+ fn prepare_union_metadata < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
1245
+ union_type : Ty < ' tcx > ,
1246
+ unique_type_id : UniqueTypeId ,
1247
+ span : Span )
1248
+ -> RecursiveTypeDescription < ' tcx > {
1249
+ let union_name = compute_debuginfo_type_name ( cx, union_type, false ) ;
1250
+ let union_llvm_type = type_of:: in_memory_type_of ( cx, union_type) ;
1251
+
1252
+ let ( union_def_id, variant, substs) = match union_type. sty {
1253
+ ty:: TyUnion ( def, substs) => ( def. did , def. struct_variant ( ) , substs) ,
1254
+ _ => bug ! ( "prepare_union_metadata on a non-union" )
1255
+ } ;
1256
+
1257
+ let ( containing_scope, _) = get_namespace_and_span_for_item ( cx, union_def_id) ;
1258
+
1259
+ let union_metadata_stub = create_union_stub ( cx,
1260
+ union_llvm_type,
1261
+ & union_name,
1262
+ unique_type_id,
1263
+ containing_scope) ;
1264
+
1265
+ create_and_register_recursive_type_forward_declaration (
1266
+ cx,
1267
+ union_type,
1268
+ unique_type_id,
1269
+ union_metadata_stub,
1270
+ union_llvm_type,
1271
+ UnionMDF ( UnionMemberDescriptionFactory {
1272
+ variant : variant,
1273
+ substs : substs,
1274
+ span : span,
1275
+ } )
1276
+ )
1277
+ }
1212
1278
1213
1279
//=-----------------------------------------------------------------------------
1214
1280
// Enums
@@ -1798,6 +1864,42 @@ fn create_struct_stub(cx: &CrateContext,
1798
1864
return metadata_stub;
1799
1865
}
1800
1866
1867
+ fn create_union_stub ( cx : & CrateContext ,
1868
+ union_llvm_type : Type ,
1869
+ union_type_name : & str ,
1870
+ unique_type_id : UniqueTypeId ,
1871
+ containing_scope : DIScope )
1872
+ -> DICompositeType {
1873
+ let ( union_size, union_align) = size_and_align_of ( cx, union_llvm_type) ;
1874
+
1875
+ let unique_type_id_str = debug_context ( cx) . type_map
1876
+ . borrow ( )
1877
+ . get_unique_type_id_as_string ( unique_type_id) ;
1878
+ let name = CString :: new ( union_type_name) . unwrap ( ) ;
1879
+ let unique_type_id = CString :: new ( unique_type_id_str. as_bytes ( ) ) . unwrap ( ) ;
1880
+ let metadata_stub = unsafe {
1881
+ // LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
1882
+ // pointer will lead to hard to trace and debug LLVM assertions
1883
+ // later on in llvm/lib/IR/Value.cpp.
1884
+ let empty_array = create_DIArray ( DIB ( cx) , & [ ] ) ;
1885
+
1886
+ llvm:: LLVMRustDIBuilderCreateUnionType (
1887
+ DIB ( cx) ,
1888
+ containing_scope,
1889
+ name. as_ptr ( ) ,
1890
+ unknown_file_metadata ( cx) ,
1891
+ UNKNOWN_LINE_NUMBER ,
1892
+ bytes_to_bits ( union_size) ,
1893
+ bytes_to_bits ( union_align) ,
1894
+ 0 , // Flags
1895
+ empty_array,
1896
+ 0 , // RuntimeLang
1897
+ unique_type_id. as_ptr ( ) )
1898
+ } ;
1899
+
1900
+ return metadata_stub;
1901
+ }
1902
+
1801
1903
/// Creates debug information for the given global variable.
1802
1904
///
1803
1905
/// Adds the created metadata nodes directly to the crate's IR.
0 commit comments