@@ -786,7 +786,10 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
786786 usage_site_span) . finalize ( cx)
787787 }
788788 ty:: TyUnion ( ..) => {
789- unimplemented ! ( ) ;
789+ prepare_union_metadata ( cx,
790+ t,
791+ unique_type_id,
792+ usage_site_span) . finalize ( cx)
790793 }
791794 ty:: TyTuple ( ref elements) => {
792795 prepare_tuple_metadata ( cx,
@@ -1038,6 +1041,7 @@ enum MemberDescriptionFactory<'tcx> {
10381041 StructMDF ( StructMemberDescriptionFactory < ' tcx > ) ,
10391042 TupleMDF ( TupleMemberDescriptionFactory < ' tcx > ) ,
10401043 EnumMDF ( EnumMemberDescriptionFactory < ' tcx > ) ,
1044+ UnionMDF ( UnionMemberDescriptionFactory < ' tcx > ) ,
10411045 VariantMDF ( VariantMemberDescriptionFactory < ' tcx > )
10421046}
10431047
@@ -1054,6 +1058,9 @@ impl<'tcx> MemberDescriptionFactory<'tcx> {
10541058 EnumMDF ( ref this) => {
10551059 this. create_member_descriptions ( cx)
10561060 }
1061+ UnionMDF ( ref this) => {
1062+ this. create_member_descriptions ( cx)
1063+ }
10571064 VariantMDF ( ref this) => {
10581065 this. create_member_descriptions ( cx)
10591066 }
@@ -1154,7 +1161,6 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
11541161 )
11551162}
11561163
1157-
11581164//=-----------------------------------------------------------------------------
11591165// Tuples
11601166//=-----------------------------------------------------------------------------
@@ -1209,6 +1215,66 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
12091215 )
12101216}
12111217
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+ }
12121278
12131279//=-----------------------------------------------------------------------------
12141280// Enums
@@ -1798,6 +1864,42 @@ fn create_struct_stub(cx: &CrateContext,
17981864 return metadata_stub;
17991865}
18001866
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+
18011903/// Creates debug information for the given global variable.
18021904///
18031905/// Adds the created metadata nodes directly to the crate's IR.
0 commit comments