| ... | ... | @@ -1909,6 +1909,9 @@ pub const DeclGen = struct { |
| 1909 | 1909 | const gop = try dg.object.di_type_map.getOrPut(gpa, ty); |
| 1910 | 1910 | if (gop.found_existing) return gop.value_ptr.*; |
| 1911 | 1911 | 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()); |
| 1912 | 1915 | const target = dg.module.getTarget(); |
| 1913 | 1916 | const dib = dg.object.di_builder.?; |
| 1914 | 1917 | switch (ty.zigTypeTag()) { |
| ... | ... | @@ -2084,7 +2087,7 @@ pub const DeclGen = struct { |
| 2084 | 2087 | ), |
| 2085 | 2088 | }; |
| 2086 | 2089 | |
| 2087 | | const replacement_di_type = dib.createStructType( |
| 2090 | const replacement_di_ty = dib.createStructType( |
| 2088 | 2091 | compile_unit_scope, |
| 2089 | 2092 | name.ptr, |
| 2090 | 2093 | di_file, |
| ... | ... | @@ -2099,10 +2102,10 @@ pub const DeclGen = struct { |
| 2099 | 2102 | null, // vtable holder |
| 2100 | 2103 | "", // unique id |
| 2101 | 2104 | ); |
| 2102 | | dib.replaceTemporary(fwd_decl, replacement_di_type); |
| 2105 | dib.replaceTemporary(fwd_decl, replacement_di_ty); |
| 2103 | 2106 | // 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; |
| 2106 | 2109 | } |
| 2107 | 2110 | |
| 2108 | 2111 | const elem_di_ty = try lowerDebugType(dg, ptr_info.pointee_type); |
| ... | ... | @@ -2118,6 +2121,10 @@ pub const DeclGen = struct { |
| 2118 | 2121 | return ptr_di_ty; |
| 2119 | 2122 | }, |
| 2120 | 2123 | .Opaque => { |
| 2124 | if (ty.tag() == .anyopaque) { |
| 2125 | gop.value_ptr.* = dib.createBasicType("anyopaque", 0, DW.ATE.signed); |
| 2126 | return gop.value_ptr.*; |
| 2127 | } |
| 2121 | 2128 | const name = try ty.nameAlloc(gpa); // TODO this is a leak |
| 2122 | 2129 | const owner_decl = ty.getOwnerDecl(); |
| 2123 | 2130 | const opaque_di_ty = dib.createForwardDeclType( |
| ... | ... | @@ -2144,7 +2151,15 @@ pub const DeclGen = struct { |
| 2144 | 2151 | return array_di_ty; |
| 2145 | 2152 | }, |
| 2146 | 2153 | .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; |
| 2148 | 2163 | }, |
| 2149 | 2164 | .Optional => { |
| 2150 | 2165 | const name = try ty.nameAlloc(gpa); // TODO this is a leak |
| ... | ... | @@ -2209,7 +2224,7 @@ pub const DeclGen = struct { |
| 2209 | 2224 | ), |
| 2210 | 2225 | }; |
| 2211 | 2226 | |
| 2212 | | const replacement_di_type = dib.createStructType( |
| 2227 | const replacement_di_ty = dib.createStructType( |
| 2213 | 2228 | compile_unit_scope, |
| 2214 | 2229 | name.ptr, |
| 2215 | 2230 | di_file, |
| ... | ... | @@ -2224,10 +2239,10 @@ pub const DeclGen = struct { |
| 2224 | 2239 | null, // vtable holder |
| 2225 | 2240 | "", // unique id |
| 2226 | 2241 | ); |
| 2227 | | dib.replaceTemporary(fwd_decl, replacement_di_type); |
| 2242 | dib.replaceTemporary(fwd_decl, replacement_di_ty); |
| 2228 | 2243 | // 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; |
| 2231 | 2246 | }, |
| 2232 | 2247 | .ErrorUnion => { |
| 2233 | 2248 | const err_set_ty = ty.errorUnionSet(); |
| ... | ... | @@ -2286,7 +2301,7 @@ pub const DeclGen = struct { |
| 2286 | 2301 | ), |
| 2287 | 2302 | }; |
| 2288 | 2303 | |
| 2289 | | const replacement_di_type = dib.createStructType( |
| 2304 | const replacement_di_ty = dib.createStructType( |
| 2290 | 2305 | compile_unit_scope, |
| 2291 | 2306 | name.ptr, |
| 2292 | 2307 | di_file, |
| ... | ... | @@ -2301,10 +2316,10 @@ pub const DeclGen = struct { |
| 2301 | 2316 | null, // vtable holder |
| 2302 | 2317 | "", // unique id |
| 2303 | 2318 | ); |
| 2304 | | dib.replaceTemporary(fwd_decl, replacement_di_type); |
| 2319 | dib.replaceTemporary(fwd_decl, replacement_di_ty); |
| 2305 | 2320 | // 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; |
| 2308 | 2323 | }, |
| 2309 | 2324 | .ErrorSet => { |
| 2310 | 2325 | // TODO make this a proper enum with all the error codes in it. |
| ... | ... | @@ -2313,20 +2328,80 @@ pub const DeclGen = struct { |
| 2313 | 2328 | return gop.value_ptr.*; |
| 2314 | 2329 | }, |
| 2315 | 2330 | .Struct => { |
| 2316 | | const owner_decl = ty.getOwnerDecl(); |
| 2317 | | |
| 2331 | const compile_unit_scope = dg.object.di_compile_unit.?.toScope(); |
| 2318 | 2332 | const name = try ty.nameAlloc(gpa); // TODO this is a leak |
| 2319 | 2333 | const fwd_decl = dib.createReplaceableCompositeType( |
| 2320 | 2334 | DW.TAG.structure_type, |
| 2321 | 2335 | name.ptr, |
| 2322 | | dg.object.di_compile_unit.?.toScope(), |
| 2336 | compile_unit_scope, |
| 2323 | 2337 | null, // file |
| 2324 | 2338 | 0, // line |
| 2325 | 2339 | ); |
| 2326 | 2340 | gop.value_ptr.* = fwd_decl; |
| 2327 | 2341 | |
| 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 | |
| 2328 | 2402 | const TODO_implement_this = true; // TODO |
| 2329 | 2403 | if (TODO_implement_this or !ty.hasRuntimeBits()) { |
| 2404 | const owner_decl = ty.getOwnerDecl(); |
| 2330 | 2405 | const struct_di_ty = try dg.makeEmptyNamespaceDIType(owner_decl); |
| 2331 | 2406 | dib.replaceTemporary(fwd_decl, struct_di_ty); |
| 2332 | 2407 | // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType` |
| ... | ... | @@ -2336,65 +2411,6 @@ pub const DeclGen = struct { |
| 2336 | 2411 | } |
| 2337 | 2412 | @panic("TODO debug info type for struct"); |
| 2338 | 2413 | |
| 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 | | |
| 2398 | 2414 | //const struct_obj = ty.castTag(.@"struct").?.data; |
| 2399 | 2415 | |
| 2400 | 2416 | //if (struct_obj.layout == .Packed) { |
| ... | ... | @@ -2554,7 +2570,10 @@ pub const DeclGen = struct { |
| 2554 | 2570 | defer param_di_types.deinit(); |
| 2555 | 2571 | |
| 2556 | 2572 | // 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; |
| 2558 | 2577 | try param_di_types.append(try dg.lowerDebugType(di_ret_ty)); |
| 2559 | 2578 | |
| 2560 | 2579 | if (sret) { |