@@ -1909,6 +1909,9 @@ pub const DeclGen = struct {
19091909 const gop = try dg .object .di_type_map .getOrPut (gpa , ty );
19101910 if (gop .found_existing ) return gop .value_ptr .* ;
19111911 errdefer assert (dg .object .di_type_map .remove (ty ));
1912+ // The Type memory is ephemeral; since we want to store a longer-lived
1913+ // reference, we need to copy it here.
1914+ gop .key_ptr .* = try ty .copy (dg .object .type_map_arena .allocator ());
19121915 const target = dg .module .getTarget ();
19131916 const dib = dg .object .di_builder .? ;
19141917 switch (ty .zigTypeTag ()) {
@@ -2084,7 +2087,7 @@ pub const DeclGen = struct {
20842087 ),
20852088 };
20862089
2087- const replacement_di_type = dib .createStructType (
2090+ const replacement_di_ty = dib .createStructType (
20882091 compile_unit_scope ,
20892092 name .ptr ,
20902093 di_file ,
@@ -2099,10 +2102,10 @@ pub const DeclGen = struct {
20992102 null , // vtable holder
21002103 "" , // unique id
21012104 );
2102- dib .replaceTemporary (fwd_decl , replacement_di_type );
2105+ dib .replaceTemporary (fwd_decl , replacement_di_ty );
21032106 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2104- try dg .object .di_type_map .put (gpa , ty , replacement_di_type );
2105- return replacement_di_type ;
2107+ try dg .object .di_type_map .put (gpa , ty , replacement_di_ty );
2108+ return replacement_di_ty ;
21062109 }
21072110
21082111 const elem_di_ty = try lowerDebugType (dg , ptr_info .pointee_type );
@@ -2118,6 +2121,10 @@ pub const DeclGen = struct {
21182121 return ptr_di_ty ;
21192122 },
21202123 .Opaque = > {
2124+ if (ty .tag () == .anyopaque ) {
2125+ gop .value_ptr .* = dib .createBasicType ("anyopaque" , 0 , DW .ATE .signed );
2126+ return gop .value_ptr .* ;
2127+ }
21212128 const name = try ty .nameAlloc (gpa ); // TODO this is a leak
21222129 const owner_decl = ty .getOwnerDecl ();
21232130 const opaque_di_ty = dib .createForwardDeclType (
@@ -2144,7 +2151,15 @@ pub const DeclGen = struct {
21442151 return array_di_ty ;
21452152 },
21462153 .Vector = > {
2147- @panic ("TODO debug info type for vector" );
2154+ const vector_di_ty = dib .createVectorType (
2155+ ty .abiSize (target ) * 8 ,
2156+ ty .abiAlignment (target ) * 8 ,
2157+ try lowerDebugType (dg , ty .childType ()),
2158+ ty .vectorLen (),
2159+ );
2160+ // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2161+ try dg .object .di_type_map .put (gpa , ty , vector_di_ty );
2162+ return vector_di_ty ;
21482163 },
21492164 .Optional = > {
21502165 const name = try ty .nameAlloc (gpa ); // TODO this is a leak
@@ -2209,7 +2224,7 @@ pub const DeclGen = struct {
22092224 ),
22102225 };
22112226
2212- const replacement_di_type = dib .createStructType (
2227+ const replacement_di_ty = dib .createStructType (
22132228 compile_unit_scope ,
22142229 name .ptr ,
22152230 di_file ,
@@ -2224,10 +2239,10 @@ pub const DeclGen = struct {
22242239 null , // vtable holder
22252240 "" , // unique id
22262241 );
2227- dib .replaceTemporary (fwd_decl , replacement_di_type );
2242+ dib .replaceTemporary (fwd_decl , replacement_di_ty );
22282243 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2229- try dg .object .di_type_map .put (gpa , ty , replacement_di_type );
2230- return replacement_di_type ;
2244+ try dg .object .di_type_map .put (gpa , ty , replacement_di_ty );
2245+ return replacement_di_ty ;
22312246 },
22322247 .ErrorUnion = > {
22332248 const err_set_ty = ty .errorUnionSet ();
@@ -2286,7 +2301,7 @@ pub const DeclGen = struct {
22862301 ),
22872302 };
22882303
2289- const replacement_di_type = dib .createStructType (
2304+ const replacement_di_ty = dib .createStructType (
22902305 compile_unit_scope ,
22912306 name .ptr ,
22922307 di_file ,
@@ -2301,10 +2316,10 @@ pub const DeclGen = struct {
23012316 null , // vtable holder
23022317 "" , // unique id
23032318 );
2304- dib .replaceTemporary (fwd_decl , replacement_di_type );
2319+ dib .replaceTemporary (fwd_decl , replacement_di_ty );
23052320 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2306- try dg .object .di_type_map .put (gpa , ty , replacement_di_type );
2307- return replacement_di_type ;
2321+ try dg .object .di_type_map .put (gpa , ty , replacement_di_ty );
2322+ return replacement_di_ty ;
23082323 },
23092324 .ErrorSet = > {
23102325 // TODO make this a proper enum with all the error codes in it.
@@ -2313,20 +2328,80 @@ pub const DeclGen = struct {
23132328 return gop .value_ptr .* ;
23142329 },
23152330 .Struct = > {
2316- const owner_decl = ty .getOwnerDecl ();
2317-
2331+ const compile_unit_scope = dg .object .di_compile_unit .? .toScope ();
23182332 const name = try ty .nameAlloc (gpa ); // TODO this is a leak
23192333 const fwd_decl = dib .createReplaceableCompositeType (
23202334 DW .TAG .structure_type ,
23212335 name .ptr ,
2322- dg . object . di_compile_unit .? . toScope () ,
2336+ compile_unit_scope ,
23232337 null , // file
23242338 0 , // line
23252339 );
23262340 gop .value_ptr .* = fwd_decl ;
23272341
2342+ if (ty .isTupleOrAnonStruct ()) {
2343+ const tuple = ty .tupleFields ();
2344+
2345+ var di_fields : std .ArrayListUnmanaged (* llvm .DIType ) = .{};
2346+ defer di_fields .deinit (gpa );
2347+
2348+ try di_fields .ensureUnusedCapacity (gpa , tuple .types .len );
2349+
2350+ comptime assert (struct_layout_version == 2 );
2351+ var offset : u64 = 0 ;
2352+
2353+ for (tuple .types ) | field_ty , i | {
2354+ const field_val = tuple .values [i ];
2355+ if (field_val .tag () != .unreachable_value ) continue ;
2356+
2357+ const field_size = field_ty .abiSize (target );
2358+ const field_align = field_ty .abiAlignment (target );
2359+ const field_offset = std .mem .alignForwardGeneric (u64 , offset , field_align );
2360+ offset = field_offset + field_size ;
2361+
2362+ const field_name = if (ty .castTag (.anon_struct )) | payload |
2363+ try gpa .dupeZ (u8 , payload .data .names [i ])
2364+ else
2365+ try std .fmt .allocPrintZ (gpa , "{d}" , .{i });
2366+ defer gpa .free (field_name );
2367+
2368+ try di_fields .append (gpa , dib .createMemberType (
2369+ fwd_decl .toScope (),
2370+ field_name ,
2371+ null , // file
2372+ 0 , // line
2373+ field_size * 8 , // size in bits
2374+ field_align * 8 , // align in bits
2375+ field_offset * 8 , // offset in bits
2376+ 0 , // flags
2377+ try dg .lowerDebugType (field_ty ),
2378+ ));
2379+ }
2380+
2381+ const replacement_di_ty = dib .createStructType (
2382+ compile_unit_scope ,
2383+ name .ptr ,
2384+ null , // file
2385+ 0 , // line
2386+ ty .abiSize (target ) * 8 , // size in bits
2387+ ty .abiAlignment (target ) * 8 , // align in bits
2388+ 0 , // flags
2389+ null , // derived from
2390+ di_fields .items .ptr ,
2391+ @intCast (c_int , di_fields .items .len ),
2392+ 0 , // run time lang
2393+ null , // vtable holder
2394+ "" , // unique id
2395+ );
2396+ dib .replaceTemporary (fwd_decl , replacement_di_ty );
2397+ // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2398+ try dg .object .di_type_map .put (gpa , ty , replacement_di_ty );
2399+ return replacement_di_ty ;
2400+ }
2401+
23282402 const TODO_implement_this = true ; // TODO
23292403 if (TODO_implement_this or ! ty .hasRuntimeBits ()) {
2404+ const owner_decl = ty .getOwnerDecl ();
23302405 const struct_di_ty = try dg .makeEmptyNamespaceDIType (owner_decl );
23312406 dib .replaceTemporary (fwd_decl , struct_di_ty );
23322407 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
@@ -2336,65 +2411,6 @@ pub const DeclGen = struct {
23362411 }
23372412 @panic ("TODO debug info type for struct" );
23382413
2339- //const gop = try dg.object.type_map.getOrPut(gpa, ty);
2340- //if (gop.found_existing) return gop.value_ptr.*;
2341-
2342- //// The Type memory is ephemeral; since we want to store a longer-lived
2343- //// reference, we need to copy it here.
2344- //gop.key_ptr.* = try ty.copy(dg.object.type_map_arena.allocator());
2345-
2346- //if (ty.isTupleOrAnonStruct()) {
2347- // const tuple = ty.tupleFields();
2348- // const llvm_struct_ty = dg.context.structCreateNamed("");
2349- // gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
2350-
2351- // var llvm_field_types: std.ArrayListUnmanaged(*const llvm.Type) = .{};
2352- // defer llvm_field_types.deinit(gpa);
2353-
2354- // try llvm_field_types.ensureUnusedCapacity(gpa, tuple.types.len);
2355-
2356- // comptime assert(struct_layout_version == 2);
2357- // var offset: u64 = 0;
2358- // var big_align: u32 = 0;
2359-
2360- // for (tuple.types) |field_ty, i| {
2361- // const field_val = tuple.values[i];
2362- // if (field_val.tag() != .unreachable_value) continue;
2363-
2364- // const field_align = field_ty.abiAlignment(target);
2365- // big_align = @maximum(big_align, field_align);
2366- // const prev_offset = offset;
2367- // offset = std.mem.alignForwardGeneric(u64, offset, field_align);
2368-
2369- // const padding_len = offset - prev_offset;
2370- // if (padding_len > 0) {
2371- // const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
2372- // try llvm_field_types.append(gpa, llvm_array_ty);
2373- // }
2374- // const field_llvm_ty = try dg.llvmType(field_ty);
2375- // try llvm_field_types.append(gpa, field_llvm_ty);
2376-
2377- // offset += field_ty.abiSize(target);
2378- // }
2379- // {
2380- // const prev_offset = offset;
2381- // offset = std.mem.alignForwardGeneric(u64, offset, big_align);
2382- // const padding_len = offset - prev_offset;
2383- // if (padding_len > 0) {
2384- // const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
2385- // try llvm_field_types.append(gpa, llvm_array_ty);
2386- // }
2387- // }
2388-
2389- // llvm_struct_ty.structSetBody(
2390- // llvm_field_types.items.ptr,
2391- // @intCast(c_uint, llvm_field_types.items.len),
2392- // .False,
2393- // );
2394-
2395- // return llvm_struct_ty;
2396- //}
2397-
23982414 //const struct_obj = ty.castTag(.@"struct").?.data;
23992415
24002416 //if (struct_obj.layout == .Packed) {
@@ -2554,7 +2570,10 @@ pub const DeclGen = struct {
25542570 defer param_di_types .deinit ();
25552571
25562572 // Return type goes first.
2557- const di_ret_ty = if (sret ) Type .void else fn_info .return_type ;
2573+ const di_ret_ty = if (sret or ! fn_info .return_type .hasRuntimeBits ())
2574+ Type .void
2575+ else
2576+ fn_info .return_type ;
25582577 try param_di_types .append (try dg .lowerDebugType (di_ret_ty ));
25592578
25602579 if (sret ) {
0 commit comments