authorgravatar for jonathan.haehne@hotmail.comTau <jonathan.haehne@hotmail.com> 2024-06-21 00:53:11+02:00
committergravatar for jonathan.haehne@hotmail.comTau <jonathan.haehne@hotmail.com> 2024-07-19 17:51:37+02:00
log359bbdd5748779a4e1b12706e0be704cfacb5078
treee68f19e9bec8e2771d6442aad19764848c0f80ee
parent876258abe46273aeac7c9791c7ec69bceb29f5ae

llvm: encode variables as DW_TAG_imported_declaration

Now we get working global variable lookup in GDB! LLDB still re-mangles, and it looks like we can't do much about that for now. Also: translate non-owning type declarations into typedefs.

3 files changed, 550 insertions(+), 412 deletions(-)

src/codegen/llvm.zig+412-389
......@@ -814,14 +814,17 @@ pub const Object = struct {
814814
815815 debug_enums_fwd_ref: Builder.Metadata,
816816 debug_globals_fwd_ref: Builder.Metadata,
817 debug_imports_fwd_ref: Builder.Metadata,
817818
818819 debug_enums: std.ArrayListUnmanaged(Builder.Metadata),
819820 debug_globals: std.ArrayListUnmanaged(Builder.Metadata),
821 debug_imports: std.ArrayListUnmanaged(Builder.Metadata),
820822
821823 debug_file_map: std.AutoHashMapUnmanaged(*const Zcu.File, Builder.Metadata),
822824 debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata),
823825
824 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),
826 // The value says whether this namespace's type is runtime-required.
827 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(Type, bool),
825828
826829 target: std.Target,
827830 /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,
......@@ -884,7 +887,7 @@ pub const Object = struct {
884887
885888 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }});
886889
887 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref =
890 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref, const debug_imports_fwd_ref =
888891 if (!builder.strip)
889892 debug_info: {
890893 // We fully resolve all paths at this point to avoid lack of
......@@ -916,6 +919,7 @@ pub const Object = struct {
916919
917920 const debug_enums_fwd_ref = try builder.debugForwardReference();
918921 const debug_globals_fwd_ref = try builder.debugForwardReference();
922 const debug_imports_fwd_ref = try builder.debugForwardReference();
919923
920924 const debug_compile_unit = try builder.debugCompileUnit(
921925 debug_file,
......@@ -928,6 +932,7 @@ pub const Object = struct {
928932 }),
929933 debug_enums_fwd_ref,
930934 debug_globals_fwd_ref,
935 debug_imports_fwd_ref,
931936 .{ .optimized = comp.root_mod.optimize_mode != .Debug },
932937 );
933938
......@@ -983,8 +988,8 @@ pub const Object = struct {
983988 }
984989
985990 try builder.debugNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit});
986 break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref };
987 } else .{.none} ** 3;
991 break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref, debug_imports_fwd_ref };
992 } else .{.none} ** 4;
988993
989994 const obj = try arena.create(Object);
990995 obj.* = .{
......@@ -997,8 +1002,10 @@ pub const Object = struct {
9971002 .debug_compile_unit = debug_compile_unit,
9981003 .debug_enums_fwd_ref = debug_enums_fwd_ref,
9991004 .debug_globals_fwd_ref = debug_globals_fwd_ref,
1005 .debug_imports_fwd_ref = debug_imports_fwd_ref,
10001006 .debug_enums = .{},
10011007 .debug_globals = .{},
1008 .debug_imports = .{},
10021009 .debug_file_map = .{},
10031010 .debug_type_map = .{},
10041011 .debug_unresolved_namespace_scopes = .{},
......@@ -1151,6 +1158,11 @@ pub const Object = struct {
11511158 self.debug_globals_fwd_ref,
11521159 try self.builder.debugTuple(self.debug_globals.items),
11531160 );
1161
1162 self.builder.debugForwardReferenceSetType(
1163 self.debug_imports_fwd_ref,
1164 try self.builder.debugTuple(self.debug_imports.items),
1165 );
11541166 }
11551167 }
11561168
......@@ -1634,7 +1646,7 @@ pub const Object = struct {
16341646
16351647 const line_number = decl.navSrcLine(zcu) + 1;
16361648 const is_internal_linkage = decl.val.getExternFunc(zcu) == null;
1637 const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu));
1649 const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu), true);
16381650
16391651 const subprogram = try o.builder.debugSubprogram(
16401652 file,
......@@ -1904,6 +1916,7 @@ pub const Object = struct {
19041916 pub fn lowerDebugType(
19051917 o: *Object,
19061918 ty: Type,
1919 required_by_runtime: bool,
19071920 ) Allocator.Error!Builder.Metadata {
19081921 assert(!o.builder.strip);
19091922
......@@ -1913,8 +1926,13 @@ pub const Object = struct {
19131926 const zcu = pt.zcu;
19141927 const ip = &zcu.intern_pool;
19151928
1916 if (o.debug_type_map.get(ty)) |debug_type| return debug_type;
1917
1929 if (o.debug_type_map.get(ty)) |debug_type| {
1930 if (required_by_runtime) {
1931 if (o.debug_unresolved_namespace_scopes.getEntry(ty)) |entry|
1932 entry.value_ptr.* = true;
1933 }
1934 return debug_type;
1935 }
19181936
19191937 switch (ty.zigTypeTag(zcu)) {
19201938 .Void,
......@@ -1988,7 +2006,7 @@ pub const Object = struct {
19882006 },
19892007 },
19902008 });
1991 const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty);
2009 const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty, required_by_runtime);
19922010 try o.debug_type_map.put(gpa, ty, debug_ptr_type);
19932011 return debug_ptr_type;
19942012 }
......@@ -2019,7 +2037,7 @@ pub const Object = struct {
20192037 .none, // File
20202038 debug_fwd_ref,
20212039 0, // Line
2022 try o.lowerDebugType(ptr_ty),
2040 try o.lowerDebugType(ptr_ty, required_by_runtime),
20232041 ptr_size * 8,
20242042 (ptr_align.toByteUnits() orelse 0) * 8,
20252043 0, // Offset
......@@ -2030,7 +2048,7 @@ pub const Object = struct {
20302048 .none, // File
20312049 debug_fwd_ref,
20322050 0, // Line
2033 try o.lowerDebugType(len_ty),
2051 try o.lowerDebugType(len_ty, required_by_runtime),
20342052 len_size * 8,
20352053 (len_align.toByteUnits() orelse 0) * 8,
20362054 len_offset * 8,
......@@ -2059,7 +2077,7 @@ pub const Object = struct {
20592077 return debug_slice_type;
20602078 }
20612079
2062 const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child));
2080 const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child), required_by_runtime);
20632081
20642082 const name = try o.allocTypeName(ty);
20652083 defer gpa.free(name);
......@@ -2089,7 +2107,7 @@ pub const Object = struct {
20892107 .none, // File
20902108 .none, // Scope
20912109 0, // Line
2092 try o.lowerDebugType(ty.childType(zcu)),
2110 try o.lowerDebugType(ty.childType(zcu), required_by_runtime),
20932111 ty.abiSize(pt) * 8,
20942112 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
20952113 try o.builder.debugTuple(&.{
......@@ -2124,7 +2142,7 @@ pub const Object = struct {
21242142 try o.builder.metadataString("bool"),
21252143 1,
21262144 ),
2127 else => try o.lowerDebugType(ty.childType(zcu)),
2145 else => try o.lowerDebugType(ty.childType(zcu), required_by_runtime),
21282146 };
21292147
21302148 const debug_vector_type = try o.builder.debugVectorType(
......@@ -2166,7 +2184,7 @@ pub const Object = struct {
21662184 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
21672185
21682186 if (ty.optionalReprIsPayload(zcu)) {
2169 const debug_optional_type = try o.lowerDebugType(child_ty);
2187 const debug_optional_type = try o.lowerDebugType(child_ty, required_by_runtime);
21702188
21712189 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type);
21722190
......@@ -2189,7 +2207,7 @@ pub const Object = struct {
21892207 .none, // File
21902208 debug_fwd_ref,
21912209 0, // Line
2192 try o.lowerDebugType(child_ty),
2210 try o.lowerDebugType(child_ty, required_by_runtime),
21932211 payload_size * 8,
21942212 (payload_align.toByteUnits() orelse 0) * 8,
21952213 0, // Offset
......@@ -2200,7 +2218,7 @@ pub const Object = struct {
22002218 .none,
22012219 debug_fwd_ref,
22022220 0,
2203 try o.lowerDebugType(non_null_ty),
2221 try o.lowerDebugType(non_null_ty, required_by_runtime),
22042222 non_null_size * 8,
22052223 (non_null_align.toByteUnits() orelse 0) * 8,
22062224 non_null_offset * 8,
......@@ -2232,7 +2250,7 @@ pub const Object = struct {
22322250 const payload_ty = ty.errorUnionPayload(zcu);
22332251 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
22342252 // TODO: Maybe remove?
2235 const debug_error_union_type = try o.lowerDebugType(Type.anyerror);
2253 const debug_error_union_type = try o.lowerDebugType(Type.anyerror, required_by_runtime);
22362254 try o.debug_type_map.put(gpa, ty, debug_error_union_type);
22372255 return debug_error_union_type;
22382256 }
......@@ -2269,7 +2287,7 @@ pub const Object = struct {
22692287 .none, // File
22702288 debug_fwd_ref,
22712289 0, // Line
2272 try o.lowerDebugType(Type.anyerror),
2290 try o.lowerDebugType(Type.anyerror, required_by_runtime),
22732291 error_size * 8,
22742292 (error_align.toByteUnits() orelse 0) * 8,
22752293 error_offset * 8,
......@@ -2279,7 +2297,7 @@ pub const Object = struct {
22792297 .none, // File
22802298 debug_fwd_ref,
22812299 0, // Line
2282 try o.lowerDebugType(payload_ty),
2300 try o.lowerDebugType(payload_ty, required_by_runtime),
22832301 payload_size * 8,
22842302 (payload_align.toByteUnits() orelse 0) * 8,
22852303 payload_offset * 8,
......@@ -2321,21 +2339,21 @@ pub const Object = struct {
23212339 if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) {
23222340 const sret = firstParamSRet(fn_info, pt, target);
23232341 const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);
2324 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty));
2342 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty, required_by_runtime));
23252343
23262344 if (sret) {
23272345 const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type));
2328 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2346 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
23292347 }
23302348 } else {
2331 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void));
2349 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void, required_by_runtime));
23322350 }
23332351
23342352 if (Type.fromInterned(fn_info.return_type).isError(zcu) and
23352353 zcu.comp.config.any_error_tracing)
23362354 {
23372355 const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType());
2338 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2356 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
23392357 }
23402358
23412359 for (0..fn_info.param_types.len) |i| {
......@@ -2344,9 +2362,9 @@ pub const Object = struct {
23442362
23452363 if (isByRef(param_ty, pt)) {
23462364 const ptr_ty = try pt.singleMutPtrType(param_ty);
2347 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2365 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
23482366 } else {
2349 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty));
2367 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty, required_by_runtime));
23502368 }
23512369 }
23522370
......@@ -2367,421 +2385,419 @@ pub const Object = struct {
23672385 .Frame => @panic("TODO implement lowerDebugType for Frame types"),
23682386 .AnyFrame => @panic("TODO implement lowerDebugType for AnyFrame types"),
23692387 // These are the types that need a correct scope.
2370 .Enum,
2371 .Struct,
2372 .Union,
2373 .Opaque => {}
2388 .Enum, .Struct, .Union, .Opaque => {},
23742389 }
2390 const fwd_ref = try o.builder.debugForwardReference();
2391 try o.debug_type_map.put(gpa, ty, fwd_ref);
2392 try o.debug_unresolved_namespace_scopes.put(gpa, ty, required_by_runtime);
23752393
2394 return fwd_ref;
2395 }
23762396
2377 const owner_decl_index = ty.getOwnerDeclOrNull(zcu);
2378 const owner_decl: ?*Zcu.Decl =
2379 if (owner_decl_index) |owner| zcu.declPtr(owner) else null;
2397 fn genNamespaces(o: *Object) !void {
2398 const gpa = o.gpa;
2399 const pt = o.pt;
2400 const zcu = pt.zcu;
2401 const ip = &zcu.intern_pool;
23802402
2381 const file = if (owner_decl) |owner|
2382 try o.getDebugFile(zcu.namespacePtr(owner.src_namespace).fileScope(zcu)) else .none;
2383 const scope = if (owner_decl) |owner|
2384 try o.namespaceToDebugScope(owner.src_namespace) else o.debug_compile_unit;
2385 const line = if (owner_decl) |owner| owner.typeSrcLine(zcu) + 1 else 0;
2403 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2404 defer fields.deinit(gpa);
23862405
2406 const unresolved = &o.debug_unresolved_namespace_scopes;
2407 var unresolved_i: usize = 0;
2408 while (unresolved_i < unresolved.count()) : (unresolved_i += 1) {
2409 const ty = unresolved.keys()[unresolved_i];
2410 const required_by_runtime = unresolved.values()[unresolved_i];
23872411
2388 const name = if (owner_decl) |owner| owner.name.toSlice(ip) else try o.allocTypeName(ty);
2389 defer if (owner_decl == null) gpa.free(name);
2412 const owner_decl_index = ty.getOwnerDeclOrNull(zcu);
2413 const owner_decl: ?*Zcu.Decl =
2414 if (owner_decl_index) |owner| ip.declPtr(owner) else null;
23902415
2391 switch (ty.zigTypeTag(zcu)) {
2392 .Enum => {
2393 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2394 const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index.?);
2395 try o.debug_type_map.put(gpa, ty, debug_enum_type);
2396 return debug_enum_type;
2397 }
2416 const file = if (owner_decl) |owner|
2417 try o.getDebugFile(zcu.namespacePtr(owner.src_namespace).fileScope(zcu))
2418 else
2419 .none;
2420 const scope = if (owner_decl) |owner|
2421 try o.namespaceToDebugScope(owner.src_namespace)
2422 else
2423 o.debug_compile_unit;
2424 const line = if (owner_decl) |owner| owner.typeSrcLine(zcu) + 1 else 0;
23982425
2399 const enum_type = ip.loadEnumType(ty.toIntern());
2426 const name = if (owner_decl) |owner| owner.name.toSlice(ip) else try o.allocTypeName(ty);
2427 defer if (owner_decl == null) gpa.free(name);
24002428
2401 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
2402 defer gpa.free(enumerators);
2429 const fwd_ref = o.debug_type_map.get(ty).?;
24032430
2404 const int_ty = Type.fromInterned(enum_type.tag_ty);
2405 const int_info = ty.intInfo(zcu);
2406 assert(int_info.bits != 0);
2431 fields.clearRetainingCapacity();
24072432
2408 for (enum_type.names.get(ip), 0..) |field_name_ip, i| {
2409 var bigint_space: Value.BigIntSpace = undefined;
2410 const bigint = if (enum_type.values.len != 0)
2411 Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt)
2412 else
2413 std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst();
2433 const ns = if (ty.getNamespace(zcu)) |n| n.unwrap() else null;
2434 if (ns) |ns_id| {
2435 const namespace = ip.namespacePtr(ns_id);
2436 try fields.ensureUnusedCapacity(gpa, namespace.decls.keys().len);
24142437
2415 enumerators[i] = try o.builder.debugEnumerator(
2416 try o.builder.metadataString(field_name_ip.toSlice(ip)),
2417 int_info.signedness == .unsigned,
2418 int_info.bits,
2419 bigint,
2420 );
2421 }
2438 for (namespace.decls.keys()) |decl_id| {
2439 const decl = ip.declPtr(decl_id);
2440 const decl_name = decl.name.toSlice(ip);
24222441
2423 const debug_enum_type = try o.builder.debugEnumerationType(
2424 try o.builder.metadataString(name),
2425 file,
2426 scope,
2427 line,
2428 try o.lowerDebugType(int_ty),
2429 ty.abiSize(pt) * 8,
2430 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2431 try o.builder.debugTuple(enumerators),
2432 );
2442 if (!decl.has_tv) continue;
2443 if (decl.kind != .named) continue;
2444 if (decl.analysis != .complete) continue;
24332445
2434 try o.debug_type_map.put(gpa, ty, debug_enum_type);
2435 try o.debug_enums.append(gpa, debug_enum_type);
2436 return debug_enum_type;
2437 },
2438 .Opaque => {
2439 if (ty.toIntern() == .anyopaque_type) {
2440 const debug_opaque_type = try o.builder.debugSignedType(
2441 try o.builder.metadataString("anyopaque"),
2442 0,
2443 );
2444 try o.debug_type_map.put(gpa, ty, debug_opaque_type);
2445 return debug_opaque_type;
2446 }
2446 const decl_line = decl.typeSrcLine(zcu) + 1;
24472447
2448 const debug_opaque_type = try o.builder.debugStructType(
2449 try o.builder.metadataString(name),
2450 file,
2451 scope,
2452 line,
2453 .none, // Underlying type
2454 0, // Size
2455 0, // Align
2456 .none, // Fields
2457 );
2458 try o.debug_type_map.put(gpa, ty, debug_opaque_type);
2459 return debug_opaque_type;
2460 },
2461 .Struct => {
2462 if (zcu.typeToPackedStruct(ty)) |struct_type| {
2463 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);
2464 if (backing_int_ty != .none) {
2465 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);
2466 const builder_name = try o.builder.metadataString(name);
2467 const debug_int_type = switch (info.signedness) {
2468 .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8),
2469 .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8),
2470 };
2471 try o.debug_type_map.put(gpa, ty, debug_int_type);
2472 return debug_int_type;
2448 if (decl.val.typeOf(zcu).ip_index == .type_type) {
2449 const nested_type = decl.val.toType();
2450 // If this decl is the owner of the type, it will
2451 // already have been declared as a direct child and
2452 // will not need to be typedef'd.
2453 if (nested_type.getOwnerDeclOrNull(zcu)) |owner| {
2454 if (owner == decl_id) continue;
2455 }
2456
2457 fields.appendAssumeCapacity(try o.builder.debugTypedef(
2458 try o.builder.metadataString(decl_name),
2459 try o.getDebugFile(namespace.fileScope(zcu)),
2460 fwd_ref,
2461 decl_line,
2462 try o.lowerDebugType(nested_type, false),
2463 0, // Align
2464 ));
2465 } else if (decl.val.getVariable(zcu)) |v| {
2466 fields.appendAssumeCapacity(try o.builder.debugStaticMemberType(
2467 try o.builder.metadataString(decl_name),
2468 try o.getDebugFile(namespace.fileScope(zcu)),
2469 fwd_ref,
2470 decl_line,
2471 try o.lowerDebugType(Type.fromInterned(v.ty), false),
2472 ));
24732473 }
24742474 }
2475 }
24752476
2476 switch (ip.indexToKey(ty.toIntern())) {
2477 .anon_struct_type => |tuple| {
2478 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2479 defer fields.deinit(gpa);
2480
2481 try fields.ensureUnusedCapacity(gpa, tuple.types.len);
2482
2483 comptime assert(struct_layout_version == 2);
2484 var offset: u64 = 0;
2485
2486 const debug_fwd_ref = try o.builder.debugForwardReference();
2487
2488 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
2489 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
2490
2491 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2492 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
2493 const field_offset = field_align.forward(offset);
2494 offset = field_offset + field_size;
2495
2496 const field_name = if (tuple.names.len != 0)
2497 tuple.names.get(ip)[i].toSlice(ip)
2498 else
2499 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
2500 defer if (tuple.names.len == 0) gpa.free(field_name);
2501
2502 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2503 try o.builder.metadataString(field_name),
2504 .none, // File
2505 debug_fwd_ref,
2506 0,
2507 try o.lowerDebugType(Type.fromInterned(field_ty)),
2508 field_size * 8,
2509 (field_align.toByteUnits() orelse 0) * 8,
2510 field_offset * 8,
2511 ));
2512 }
2513
2514 const debug_struct_type = try o.builder.debugStructType(
2515 try o.builder.metadataString(name),
2516 file,
2517 scope,
2518 0, // Line
2519 .none, // Underlying type
2520 ty.abiSize(pt) * 8,
2521 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2522 try o.builder.debugTuple(fields.items),
2523 );
2477 if (!required_by_runtime) {
2478 const res = try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2479 o.builder.debugForwardReferenceSetType(fwd_ref, res);
2480 continue;
2481 }
25242482
2525 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type);
2483 const res = switch (ty.zigTypeTag(zcu)) {
2484 .Enum => res: {
2485 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2486 break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2487 }
25262488
2527 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2528 return debug_struct_type;
2529 },
2530 .struct_type => {
2531 if (!ip.loadStructType(ty.toIntern()).haveFieldTypes(ip)) {
2532 // This can happen if a struct type makes it all the way to
2533 // flush() without ever being instantiated or referenced (even
2534 // via pointer). The only reason we are hearing about it now is
2535 // that it is being used as a namespace to put other debug types
2536 // into. Therefore we can satisfy this by making an empty namespace,
2537 // rather than changing the frontend to unnecessarily resolve the
2538 // struct field types.
2539 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index.?);
2540 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2541 return debug_struct_type;
2542 }
2543 },
2544 else => {},
2545 }
2489 const enum_type = ip.loadEnumType(ty.toIntern());
25462490
2547 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2548 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index.?);
2549 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2550 return debug_struct_type;
2551 }
2491 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
2492 defer gpa.free(enumerators);
25522493
2553 const struct_type = zcu.typeToStruct(ty).?;
2494 const int_ty = Type.fromInterned(enum_type.tag_ty);
2495 const int_info = ty.intInfo(zcu);
2496 assert(int_info.bits != 0);
25542497
2555 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2556 defer fields.deinit(gpa);
2498 for (enum_type.names.get(ip), 0..) |field_name_ip, i| {
2499 var bigint_space: Value.BigIntSpace = undefined;
2500 const bigint = if (enum_type.values.len != 0)
2501 Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt)
2502 else
2503 std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst();
25572504
2558 try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
2505 enumerators[i] = try o.builder.debugEnumerator(
2506 try o.builder.metadataString(field_name_ip.toSlice(ip)),
2507 int_info.signedness == .unsigned,
2508 int_info.bits,
2509 bigint,
2510 );
2511 }
25592512
2560 const debug_fwd_ref = try o.builder.debugForwardReference();
2513 const debug_enum_type = try o.builder.debugEnumerationType(
2514 try o.builder.metadataString(name),
2515 file,
2516 scope,
2517 line,
2518 try o.lowerDebugType(int_ty, required_by_runtime),
2519 ty.abiSize(pt) * 8,
2520 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2521 try o.builder.debugTuple(enumerators),
2522 );
25612523
2562 // Set as forward reference while the type is lowered in case it references itself
2563 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
2524 try o.debug_enums.append(gpa, debug_enum_type);
2525 break :res debug_enum_type;
2526 },
2527 .Opaque => res: {
2528 if (ty.toIntern() == .anyopaque_type) {
2529 break :res try o.builder.debugSignedType(
2530 try o.builder.metadataString("anyopaque"),
2531 0,
2532 );
2533 }
25642534
2565 comptime assert(struct_layout_version == 2);
2566 var it = struct_type.iterateRuntimeOrder(ip);
2567 while (it.next()) |field_index| {
2568 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2569 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
2570 const field_size = field_ty.abiSize(pt);
2571 const field_align = pt.structFieldAlignment(
2572 struct_type.fieldAlign(ip, field_index),
2573 field_ty,
2574 struct_type.layout,
2535 const debug_opaque_type = try o.builder.debugStructType(
2536 try o.builder.metadataString(name),
2537 file,
2538 scope,
2539 line,
2540 .none, // Underlying type
2541 0, // Size
2542 0, // Align
2543 .none, // Fields
25752544 );
2576 const field_offset = ty.structFieldOffset(field_index, pt);
2545 break :res debug_opaque_type;
2546 },
2547 .Struct => res: {
2548 if (zcu.typeToPackedStruct(ty)) |struct_type| {
2549 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);
2550 if (backing_int_ty != .none) {
2551 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);
2552 const builder_name = try o.builder.metadataString(name);
2553 const debug_int_type = switch (info.signedness) {
2554 .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8),
2555 .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8),
2556 };
2557 break :res debug_int_type;
2558 }
2559 }
25772560
2578 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
2579 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
2561 switch (ip.indexToKey(ty.toIntern())) {
2562 .anon_struct_type => |tuple| {
2563 try fields.ensureUnusedCapacity(gpa, tuple.types.len);
2564
2565 comptime assert(struct_layout_version == 2);
2566 var offset: u64 = 0;
2567
2568 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
2569 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
2570
2571 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2572 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
2573 const field_offset = field_align.forward(offset);
2574 offset = field_offset + field_size;
2575
2576 const field_name = if (tuple.names.len != 0)
2577 tuple.names.get(ip)[i].toSlice(ip)
2578 else
2579 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
2580 defer if (tuple.names.len == 0) gpa.free(field_name);
2581
2582 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2583 try o.builder.metadataString(field_name),
2584 .none, // File
2585 fwd_ref,
2586 0,
2587 try o.lowerDebugType(Type.fromInterned(field_ty), required_by_runtime),
2588 field_size * 8,
2589 (field_align.toByteUnits() orelse 0) * 8,
2590 field_offset * 8,
2591 ));
2592 }
25802593
2581 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2582 try o.builder.metadataString(field_name.toSlice(ip)),
2583 file,
2584 debug_fwd_ref,
2585 0, // Line
2586 try o.lowerDebugType(field_ty),
2587 field_size * 8,
2588 (field_align.toByteUnits() orelse 0) * 8,
2589 field_offset * 8,
2590 ));
2591 }
2594 const debug_struct_type = try o.builder.debugStructType(
2595 try o.builder.metadataString(name),
2596 file,
2597 scope,
2598 0, // Line
2599 .none, // Underlying type
2600 ty.abiSize(pt) * 8,
2601 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2602 try o.builder.debugTuple(fields.items),
2603 );
25922604
2593 const debug_struct_type = try o.builder.debugStructType(
2594 try o.builder.metadataString(name),
2595 file,
2596 scope,
2597 line,
2598 .none, // Underlying type
2599 ty.abiSize(pt) * 8,
2600 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2601 try o.builder.debugTuple(fields.items),
2602 );
2605 break :res debug_struct_type;
2606 },
2607 else => {},
2608 }
26032609
2604 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type);
2610 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2611 break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2612 }
2613 const struct_type = zcu.typeToStruct(ty).?;
26052614
2606 // Set to real type now that it has been lowered fully
2607 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2608 map_ptr.* = debug_struct_type;
2615 if (!struct_type.haveLayout(ip) or !struct_type.haveFieldTypes(ip)) {
2616 break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2617 }
26092618
2610 return debug_struct_type;
2611 },
2612 .Union => {
2613 const union_type = ip.loadUnionType(ty.toIntern());
2614 if (!union_type.haveFieldTypes(ip) or
2615 !ty.hasRuntimeBitsIgnoreComptime(pt) or
2616 !union_type.haveLayout(ip))
2617 {
2618 const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index.?);
2619 try o.debug_type_map.put(gpa, ty, debug_union_type);
2620 return debug_union_type;
2621 }
2619 try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
26222620
2623 const layout = pt.getUnionLayout(union_type);
2621 comptime assert(struct_layout_version == 2);
2622 var it = struct_type.iterateRuntimeOrder(ip);
2623 while (it.next()) |field_index| {
2624 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2625 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
2626 const field_size = field_ty.abiSize(pt);
2627 const field_align = pt.structFieldAlignment(
2628 struct_type.fieldAlign(ip, field_index),
2629 field_ty,
2630 struct_type.layout,
2631 );
2632 const field_offset = ty.structFieldOffset(field_index, pt);
26242633
2625 const debug_fwd_ref = try o.builder.debugForwardReference();
2634 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
2635 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
26262636
2627 // Set as forward reference while the type is lowered in case it references itself
2628 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
2637 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2638 try o.builder.metadataString(field_name.toSlice(ip)),
2639 file,
2640 fwd_ref,
2641 0, // Line
2642 try o.lowerDebugType(field_ty, required_by_runtime),
2643 field_size * 8,
2644 (field_align.toByteUnits() orelse 0) * 8,
2645 field_offset * 8,
2646 ));
2647 }
26292648
2630 if (layout.payload_size == 0) {
2631 const debug_union_type = try o.builder.debugStructType(
2649 const debug_struct_type = try o.builder.debugStructType(
26322650 try o.builder.metadataString(name),
26332651 file,
26342652 scope,
2635 0, // Line
2653 line,
26362654 .none, // Underlying type
26372655 ty.abiSize(pt) * 8,
26382656 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2639 try o.builder.debugTuple(
2640 &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))},
2641 ),
2657 try o.builder.debugTuple(fields.items),
26422658 );
26432659
2644 // Set to real type now that it has been lowered fully
2645 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2646 map_ptr.* = debug_union_type;
2647
2648 return debug_union_type;
2649 }
2650
2651 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2652 defer fields.deinit(gpa);
2653
2654 try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len);
2655
2656 const debug_union_fwd_ref = if (layout.tag_size == 0)
2657 debug_fwd_ref
2658 else
2659 try o.builder.debugForwardReference();
2660 break :res debug_struct_type;
2661 },
2662 .Union => res: {
2663 const union_type = ip.loadUnionType(ty.toIntern());
2664 if (!union_type.haveFieldTypes(ip) or
2665 !ty.hasRuntimeBitsIgnoreComptime(pt) or
2666 !union_type.haveLayout(ip))
2667 {
2668 break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2669 }
26602670
2661 const tag_type = union_type.loadTagType(ip);
2671 const layout = pt.getUnionLayout(union_type);
26622672
2663 for (0..tag_type.names.len) |field_index| {
2664 const field_ty = union_type.field_types.get(ip)[field_index];
2665 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
2673 if (layout.payload_size == 0) {
2674 const debug_union_type = try o.builder.debugStructType(
2675 try o.builder.metadataString(name),
2676 file,
2677 scope,
2678 0, // Line
2679 .none, // Underlying type
2680 ty.abiSize(pt) * 8,
2681 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2682 try o.builder.debugTuple(
2683 &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty), required_by_runtime)},
2684 ),
2685 );
26662686
2667 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2668 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {
2669 .@"packed" => .none,
2670 .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)),
2671 };
2687 break :res debug_union_type;
2688 }
26722689
2673 const field_name = tag_type.names.get(ip)[field_index];
2674 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2675 try o.builder.metadataString(field_name.toSlice(ip)),
2676 file,
2677 debug_union_fwd_ref,
2678 0, // Line
2679 try o.lowerDebugType(Type.fromInterned(field_ty)),
2680 field_size * 8,
2681 (field_align.toByteUnits() orelse 0) * 8,
2682 0, // Offset
2683 ));
2684 }
2690 try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len);
26852691
2686 var union_name_buf: ?[:0]const u8 = null;
2687 defer if (union_name_buf) |buf| gpa.free(buf);
2688 const union_name = if (layout.tag_size == 0) name else name: {
2689 union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name});
2690 break :name union_name_buf.?;
2691 };
2692 const debug_union_fwd_ref = if (layout.tag_size == 0)
2693 fwd_ref
2694 else
2695 try o.builder.debugForwardReference();
26922696
2693 const debug_union_type = try o.builder.debugUnionType(
2694 try o.builder.metadataString(union_name),
2695 file,
2696 scope,
2697 line,
2698 .none, // Underlying type
2699 ty.abiSize(pt) * 8,
2700 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2701 try o.builder.debugTuple(fields.items),
2702 );
2697 const tag_type = union_type.loadTagType(ip);
27032698
2704 o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type);
2699 for (0..tag_type.names.len) |field_index| {
2700 const field_ty = union_type.field_types.get(ip)[field_index];
2701 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
27052702
2706 if (layout.tag_size == 0) {
2707 // Set to real type now that it has been lowered fully
2708 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2709 map_ptr.* = debug_union_type;
2703 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2704 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {
2705 .@"packed" => .none,
2706 .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)),
2707 };
27102708
2711 return debug_union_type;
2712 }
2709 const field_name = tag_type.names.get(ip)[field_index];
2710 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2711 try o.builder.metadataString(field_name.toSlice(ip)),
2712 file,
2713 debug_union_fwd_ref,
2714 0, // Line
2715 try o.lowerDebugType(Type.fromInterned(field_ty), required_by_runtime),
2716 field_size * 8,
2717 (field_align.toByteUnits() orelse 0) * 8,
2718 0, // Offset
2719 ));
2720 }
27132721
2714 var tag_offset: u64 = undefined;
2715 var payload_offset: u64 = undefined;
2716 if (layout.tag_align.compare(.gte, layout.payload_align)) {
2717 tag_offset = 0;
2718 payload_offset = layout.payload_align.forward(layout.tag_size);
2719 } else {
2720 payload_offset = 0;
2721 tag_offset = layout.tag_align.forward(layout.payload_size);
2722 }
2722 var union_name_buf: ?[:0]const u8 = null;
2723 defer if (union_name_buf) |buf| gpa.free(buf);
2724 const union_name = if (layout.tag_size == 0) name else name: {
2725 union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name});
2726 break :name union_name_buf.?;
2727 };
27232728
2724 const debug_tag_type = try o.builder.debugMemberType(
2725 try o.builder.metadataString("tag"),
2726 file, // File
2727 debug_fwd_ref,
2728 0, // Line
2729 try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty)),
2730 layout.tag_size * 8,
2731 (layout.tag_align.toByteUnits() orelse 0) * 8,
2732 tag_offset * 8,
2733 );
2729 const debug_union_type = try o.builder.debugUnionType(
2730 try o.builder.metadataString(union_name),
2731 file,
2732 scope,
2733 line,
2734 .none, // Underlying type
2735 ty.abiSize(pt) * 8,
2736 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2737 try o.builder.debugTuple(fields.items),
2738 );
27342739
2735 const debug_payload_type = try o.builder.debugMemberType(
2736 try o.builder.metadataString("payload"),
2737 file,
2738 debug_fwd_ref,
2739 0, // Line
2740 debug_union_type,
2741 layout.payload_size * 8,
2742 (layout.payload_align.toByteUnits() orelse 0) * 8,
2743 payload_offset * 8,
2744 );
2740 if (layout.tag_size == 0) {
2741 break :res debug_union_type;
2742 }
27452743
2746 const full_fields: [2]Builder.Metadata =
2747 if (layout.tag_align.compare(.gte, layout.payload_align))
2748 .{ debug_tag_type, debug_payload_type }
2749 else
2750 .{ debug_payload_type, debug_tag_type };
2744 o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type);
27512745
2752 const debug_tagged_union_type = try o.builder.debugStructType(
2753 try o.builder.metadataString(name),
2754 file, // File
2755 scope,
2756 line,
2757 .none, // Underlying type
2758 ty.abiSize(pt) * 8,
2759 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2760 try o.builder.debugTuple(&full_fields),
2761 );
2746 var tag_offset: u64 = undefined;
2747 var payload_offset: u64 = undefined;
2748 if (layout.tag_align.compare(.gte, layout.payload_align)) {
2749 tag_offset = 0;
2750 payload_offset = layout.payload_align.forward(layout.tag_size);
2751 } else {
2752 payload_offset = 0;
2753 tag_offset = layout.tag_align.forward(layout.payload_size);
2754 }
27622755
2763 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_tagged_union_type);
2756 const debug_tag_type = try o.builder.debugMemberType(
2757 try o.builder.metadataString("tag"),
2758 file, // File
2759 fwd_ref,
2760 0, // Line
2761 try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty), required_by_runtime),
2762 layout.tag_size * 8,
2763 (layout.tag_align.toByteUnits() orelse 0) * 8,
2764 tag_offset * 8,
2765 );
27642766
2765 // Set to real type now that it has been lowered fully
2766 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2767 map_ptr.* = debug_tagged_union_type;
2767 const debug_payload_type = try o.builder.debugMemberType(
2768 try o.builder.metadataString("payload"),
2769 file,
2770 fwd_ref,
2771 0, // Line
2772 debug_union_type,
2773 layout.payload_size * 8,
2774 (layout.payload_align.toByteUnits() orelse 0) * 8,
2775 payload_offset * 8,
2776 );
27682777
2769 return debug_tagged_union_type;
2770 },
2771 else => unreachable, // Handled above.
2772 }
2773 }
2778 const full_fields: [2]Builder.Metadata =
2779 if (layout.tag_align.compare(.gte, layout.payload_align))
2780 .{ debug_tag_type, debug_payload_type }
2781 else
2782 .{ debug_payload_type, debug_tag_type };
27742783
2775 fn genNamespaces(o: *Object) !void {
2776 var i: usize = 0;
2777 while (i < o.debug_unresolved_namespace_scopes.count()) : (i += 1) {
2778 const namespace_index = o.debug_unresolved_namespace_scopes.keys()[i];
2779 const fwd_ref = o.debug_unresolved_namespace_scopes.values()[i];
2784 const debug_tagged_union_type = try o.builder.debugStructType(
2785 try o.builder.metadataString(name),
2786 file, // File
2787 scope,
2788 line,
2789 .none, // Underlying type
2790 ty.abiSize(pt) * 8,
2791 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2792 try o.builder.debugTuple(&full_fields),
2793 );
27802794
2781 const namespace = o.pt.zcu.namespacePtr(namespace_index);
2782 const debug_type = try o.lowerDebugType(namespace.getType(o.pt.zcu));
2795 break :res debug_tagged_union_type;
2796 },
2797 else => unreachable, // Handled above.
2798 };
27832799
2784 o.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
2800 o.builder.debugForwardReferenceSetType(fwd_ref, res);
27852801 }
27862802 }
27872803
......@@ -2791,14 +2807,10 @@ pub const Object = struct {
27912807 const file_scope = namespace.fileScope(zcu);
27922808 if (namespace.parent == .none) return try o.getDebugFile(file_scope);
27932809
2794 const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index);
2795
2796 if (!gop.found_existing) gop.value_ptr.* = try o.builder.debugForwardReference();
2797
2798 return gop.value_ptr.*;
2810 return o.lowerDebugType(zcu.declPtr(namespace.decl_index).val.toType(), false);
27992811 }
28002812
2801 fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata {
2813 fn makeNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex, fields: []const Builder.Metadata) !Builder.Metadata {
28022814 const zcu = o.pt.zcu;
28032815 const decl = zcu.declPtr(decl_index);
28042816 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
......@@ -2810,7 +2822,7 @@ pub const Object = struct {
28102822 .none,
28112823 0,
28122824 0,
2813 .none,
2825 if (fields.len == 0) .none else try o.builder.debugTuple(fields),
28142826 );
28152827 }
28162828
......@@ -4723,6 +4735,7 @@ pub const DeclGen = struct {
47234735
47244736 if (!owner_mod.strip) {
47254737 const debug_file = try o.getDebugFile(file_scope);
4738 const debug_scope = try o.namespaceToDebugScope(decl.src_namespace);
47264739
47274740 const linkage_name = try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder));
47284741
......@@ -4730,10 +4743,10 @@ pub const DeclGen = struct {
47304743 // Imitate a C++ static member variable since neither
47314744 // GDB or LLDB can really cope with regular variables
47324745 // directly inside a struct type.
4733 const ty = try o.lowerDebugType(decl.typeOf(zcu));
4746 const ty = try o.lowerDebugType(decl.typeOf(zcu), true);
47344747 const name = try o.builder.metadataString(decl.name.toSlice(ip));
47354748
4736 break :blk try o.builder.debugGlobalVar(
4749 const variable = try o.builder.debugGlobalVar(
47374750 name,
47384751 linkage_name,
47394752 debug_file,
......@@ -4742,15 +4755,25 @@ pub const DeclGen = struct {
47424755 ty,
47434756 variable_index,
47444757 .none,
4745 .internal,
4758 .external,
47464759 );
4760
4761 try o.debug_imports.append(o.gpa, try o.builder.debugImportDeclaration(
4762 name,
4763 debug_file,
4764 debug_scope,
4765 line_number,
4766 variable,
4767 ));
4768
4769 break :blk variable;
47474770 } else try o.builder.debugGlobalVar(
47484771 linkage_name,
47494772 linkage_name,
47504773 debug_file,
47514774 debug_file,
47524775 line_number,
4753 try o.lowerDebugType(decl.typeOf(zcu)),
4776 try o.lowerDebugType(decl.typeOf(zcu), true),
47544777 variable_index,
47554778 .none,
47564779 .external,
......@@ -5209,7 +5232,7 @@ pub const FuncGen = struct {
52095232 try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)),
52105233 line_number,
52115234 line_number + func.lbrace_line,
5212 try o.lowerDebugType(fn_ty),
5235 try o.lowerDebugType(fn_ty, true),
52135236 .{
52145237 .di_flags = .{ .StaticMember = true },
52155238 .sp_flags = .{
......@@ -6759,7 +6782,7 @@ pub const FuncGen = struct {
67596782 self.file,
67606783 self.scope,
67616784 self.prev_dbg_line,
6762 try o.lowerDebugType(ptr_ty.childType(mod)),
6785 try o.lowerDebugType(ptr_ty.childType(mod), true),
67636786 );
67646787
67656788 _ = try self.wip.callIntrinsic(
......@@ -6792,7 +6815,7 @@ pub const FuncGen = struct {
67926815 self.file,
67936816 self.scope,
67946817 self.prev_dbg_line,
6795 try o.lowerDebugType(operand_ty),
6818 try o.lowerDebugType(operand_ty, true),
67966819 );
67976820
67986821 const pt = o.pt;
......@@ -8906,7 +8929,7 @@ pub const FuncGen = struct {
89068929 self.file,
89078930 self.scope,
89088931 lbrace_line,
8909 try o.lowerDebugType(inst_ty),
8932 try o.lowerDebugType(inst_ty, true),
89108933 @intCast(self.arg_index),
89118934 );
89128935
src/codegen/llvm/Builder.zig+114-22
......@@ -7652,6 +7652,8 @@ pub const Metadata = enum(u32) {
76527652 derived_pointer_type,
76537653 derived_member_type,
76547654 derived_static_member_type,
7655 derived_typedef,
7656 imported_declaration,
76557657 subroutine_type,
76567658 enumerator_unsigned,
76577659 enumerator_signed_positive,
......@@ -7699,6 +7701,8 @@ pub const Metadata = enum(u32) {
76997701 .derived_pointer_type,
77007702 .derived_member_type,
77017703 .derived_static_member_type,
7704 .derived_typedef,
7705 .imported_declaration,
77027706 .subroutine_type,
77037707 .enumerator_unsigned,
77047708 .enumerator_signed_positive,
......@@ -7816,6 +7820,7 @@ pub const Metadata = enum(u32) {
78167820 producer: MetadataString,
78177821 enums: Metadata,
78187822 globals: Metadata,
7823 imports: Metadata,
78197824 };
78207825
78217826 pub const Subprogram = struct {
......@@ -7943,6 +7948,14 @@ pub const Metadata = enum(u32) {
79437948 }
79447949 };
79457950
7951 pub const ImportedEntity = struct {
7952 name: MetadataString,
7953 file: Metadata,
7954 scope: Metadata,
7955 line: u32,
7956 entity: Metadata,
7957 };
7958
79467959 pub const SubroutineType = struct {
79477960 types_tuple: Metadata,
79487961 };
......@@ -8232,6 +8245,7 @@ pub const Metadata = enum(u32) {
82328245 DIBasicType,
82338246 DICompositeType,
82348247 DIDerivedType,
8248 DIImportedEntity,
82358249 DISubroutineType,
82368250 DIEnumerator,
82378251 DISubrange,
......@@ -9969,7 +9983,7 @@ pub fn printUnbuffered(
99699983 .enums = extra.enums,
99709984 .retainedTypes = null,
99719985 .globals = extra.globals,
9972 .imports = null,
9986 .imports = extra.imports,
99739987 .macros = null,
99749988 .dwoId = null,
99759989 .splitDebugInlining = false,
......@@ -10110,16 +10124,18 @@ pub fn printUnbuffered(
1011010124 .derived_pointer_type,
1011110125 .derived_member_type,
1011210126 .derived_static_member_type,
10127 .derived_typedef,
1011310128 => |kind| {
1011410129 const extra = self.metadataExtraData(Metadata.DerivedType, metadata_item.data);
1011510130 try metadata_formatter.specialized(.@"!", .DIDerivedType, .{
1011610131 .tag = @as(enum {
1011710132 DW_TAG_pointer_type,
1011810133 DW_TAG_member,
10134 DW_TAG_typedef,
1011910135 }, switch (kind) {
1012010136 .derived_pointer_type => .DW_TAG_pointer_type,
10121 .derived_member_type,
10122 .derived_static_member_type => .DW_TAG_member,
10137 .derived_member_type, .derived_static_member_type => .DW_TAG_member,
10138 .derived_typedef => .DW_TAG_typedef,
1012310139 else => unreachable,
1012410140 }),
1012510141 .name = switch (extra.name) {
......@@ -10142,6 +10158,22 @@ pub fn printUnbuffered(
1014210158 .annotations = null,
1014310159 }, writer);
1014410160 },
10161 .imported_declaration => {
10162 const extra = self.metadataExtraData(Metadata.ImportedEntity, metadata_item.data);
10163
10164 try metadata_formatter.specialized(.@"!", .DIImportedEntity, .{
10165 .tag = .DW_TAG_imported_declaration,
10166 .scope = extra.scope,
10167 .entity = extra.entity,
10168 .file = extra.file,
10169 .line = extra.line,
10170 .name = switch (extra.name) {
10171 .none => null,
10172 else => extra.name,
10173 },
10174 .elements = null,
10175 }, writer);
10176 },
1014510177 .subroutine_type => {
1014610178 const extra = self.metadataExtraData(Metadata.SubroutineType, metadata_item.data);
1014710179 try metadata_formatter.specialized(.@"!", .DISubroutineType, .{
......@@ -11747,10 +11779,11 @@ pub fn debugCompileUnit(
1174711779 producer: MetadataString,
1174811780 enums: Metadata,
1174911781 globals: Metadata,
11782 imports: Metadata,
1175011783 options: Metadata.CompileUnit.Options,
1175111784) Allocator.Error!Metadata {
1175211785 try self.ensureUnusedMetadataCapacity(1, Metadata.CompileUnit, 0);
11753 return self.debugCompileUnitAssumeCapacity(file, producer, enums, globals, options);
11786 return self.debugCompileUnitAssumeCapacity(file, producer, enums, globals, imports, options);
1175411787}
1175511788
1175611789pub fn debugSubprogram(
......@@ -12005,6 +12038,53 @@ pub fn debugMemberType(
1200512038 );
1200612039}
1200712040
12041pub fn debugTypedef(
12042 self: *Builder,
12043 name: MetadataString,
12044 file: Metadata,
12045 scope: Metadata,
12046 line: u32,
12047 underlying_type: Metadata,
12048 align_in_bits: u64,
12049) Allocator.Error!Metadata {
12050 try self.ensureUnusedMetadataCapacity(1, Metadata.DerivedType, 0);
12051
12052 assert(!self.strip);
12053 return self.metadataSimpleAssumeCapacity(.derived_typedef, Metadata.DerivedType{
12054 .name = name,
12055 .file = file,
12056 .scope = scope,
12057 .line = line,
12058 .underlying_type = underlying_type,
12059 .size_in_bits_lo = 0,
12060 .size_in_bits_hi = 0,
12061 .align_in_bits_lo = @truncate(align_in_bits),
12062 .align_in_bits_hi = @truncate(align_in_bits >> 32),
12063 .offset_in_bits_lo = 0,
12064 .offset_in_bits_hi = 0,
12065 });
12066}
12067
12068pub fn debugImportDeclaration(
12069 self: *Builder,
12070 name: MetadataString,
12071 file: Metadata,
12072 scope: Metadata,
12073 line: u32,
12074 entity: Metadata,
12075) Allocator.Error!Metadata {
12076 try self.ensureUnusedMetadataCapacity(1, Metadata.ImportedEntity, 0);
12077
12078 assert(!self.strip);
12079 return self.metadataSimpleAssumeCapacity(.imported_declaration, Metadata.ImportedEntity{
12080 .name = name,
12081 .file = file,
12082 .scope = scope,
12083 .line = line,
12084 .entity = entity,
12085 });
12086}
12087
1200812088pub fn debugSubroutineType(
1200912089 self: *Builder,
1201012090 types_tuple: Metadata,
......@@ -12241,6 +12321,7 @@ pub fn debugCompileUnitAssumeCapacity(
1224112321 producer: MetadataString,
1224212322 enums: Metadata,
1224312323 globals: Metadata,
12324 imports: Metadata,
1224412325 options: Metadata.CompileUnit.Options,
1224512326) Metadata {
1224612327 assert(!self.strip);
......@@ -12251,6 +12332,7 @@ pub fn debugCompileUnitAssumeCapacity(
1225112332 .producer = producer,
1225212333 .enums = enums,
1225312334 .globals = globals,
12335 .imports = imports,
1225412336 },
1225512337 );
1225612338}
......@@ -12538,22 +12620,19 @@ fn debugMemberTypeAssumeCapacity(
1253812620 static: bool,
1253912621) Metadata {
1254012622 assert(!self.strip);
12541 return self.metadataSimpleAssumeCapacity(
12542 if (static) .derived_static_member_type else .derived_member_type,
12543 Metadata.DerivedType{
12544 .name = name,
12545 .file = file,
12546 .scope = scope,
12547 .line = line,
12548 .underlying_type = underlying_type,
12549 .size_in_bits_lo = @truncate(size_in_bits),
12550 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12551 .align_in_bits_lo = @truncate(align_in_bits),
12552 .align_in_bits_hi = @truncate(align_in_bits >> 32),
12553 .offset_in_bits_lo = @truncate(offset_in_bits),
12554 .offset_in_bits_hi = @truncate(offset_in_bits >> 32),
12555 }
12556 );
12623 return self.metadataSimpleAssumeCapacity(if (static) .derived_static_member_type else .derived_member_type, Metadata.DerivedType{
12624 .name = name,
12625 .file = file,
12626 .scope = scope,
12627 .line = line,
12628 .underlying_type = underlying_type,
12629 .size_in_bits_lo = @truncate(size_in_bits),
12630 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12631 .align_in_bits_lo = @truncate(align_in_bits),
12632 .align_in_bits_hi = @truncate(align_in_bits >> 32),
12633 .offset_in_bits_lo = @truncate(offset_in_bits),
12634 .offset_in_bits_hi = @truncate(offset_in_bits >> 32),
12635 });
1255712636}
1255812637
1255912638fn debugSubroutineTypeAssumeCapacity(
......@@ -13850,6 +13929,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1385013929 },
1385113930 .enums = extra.enums,
1385213931 .globals = extra.globals,
13932 .imports = extra.imports,
1385313933 }, metadata_adapter);
1385413934 },
1385513935 .subprogram,
......@@ -13945,13 +14025,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1394514025 .derived_pointer_type,
1394614026 .derived_member_type,
1394714027 .derived_static_member_type,
14028 .derived_typedef,
1394814029 => |kind| {
1394914030 const extra = self.metadataExtraData(Metadata.DerivedType, data);
1395014031 try metadata_block.writeAbbrevAdapted(MetadataBlock.DerivedType{
1395114032 .tag = switch (kind) {
1395214033 .derived_pointer_type => DW.TAG.pointer_type,
13953 .derived_member_type,
13954 .derived_static_member_type => DW.TAG.member,
14034 .derived_member_type, .derived_static_member_type => DW.TAG.member,
14035 .derived_typedef => DW.TAG.typedef,
1395514036 else => unreachable,
1395614037 },
1395714038 .name = extra.name,
......@@ -13967,6 +14048,17 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1396714048 },
1396814049 }, metadata_adapter);
1396914050 },
14051 .imported_declaration => {
14052 const extra = self.metadataExtraData(Metadata.ImportedEntity, data);
14053 try metadata_block.writeAbbrevAdapted(MetadataBlock.ImportedEntity{
14054 .tag = DW.TAG.imported_declaration,
14055 .scope = extra.scope,
14056 .entity = extra.entity,
14057 .line = extra.line,
14058 .name = extra.name,
14059 .file = extra.file,
14060 }, metadata_adapter);
14061 },
1397014062 .subroutine_type => {
1397114063 const extra = self.metadataExtraData(Metadata.SubroutineType, data);
1397214064
src/codegen/llvm/ir.zig+24-1
......@@ -649,6 +649,7 @@ pub const MetadataBlock = struct {
649649 BasicType,
650650 CompositeType,
651651 DerivedType,
652 ImportedEntity,
652653 SubroutineType,
653654 Enumerator,
654655 Subrange,
......@@ -706,7 +707,7 @@ pub const MetadataBlock = struct {
706707 .{ .literal = 0 }, // retained types
707708 .{ .literal = 0 }, // subprograms
708709 MetadataAbbrev, // globals
709 .{ .literal = 0 }, // imported entities
710 MetadataAbbrev, // imported entities
710711 .{ .literal = 0 }, // DWO ID
711712 .{ .literal = 0 }, // macros
712713 .{ .literal = 0 }, // split debug inlining
......@@ -722,6 +723,7 @@ pub const MetadataBlock = struct {
722723 is_optimized: bool,
723724 enums: Builder.Metadata,
724725 globals: Builder.Metadata,
726 imports: Builder.Metadata,
725727 };
726728
727729 pub const Subprogram = struct {
......@@ -879,6 +881,27 @@ pub const MetadataBlock = struct {
879881 flags: Builder.Metadata.DIFlags,
880882 };
881883
884 pub const ImportedEntity = struct {
885 pub const ops = [_]AbbrevOp{
886 .{ .literal = 31 },
887 .{ .literal = 0 }, // is distinct
888 .{ .fixed = 32 }, // tag
889 MetadataAbbrev, // scope
890 MetadataAbbrev, // entity
891 LineAbbrev, // line
892 MetadataAbbrev, // name
893 MetadataAbbrev, // file
894 .{ .literal = 0 }, // elements
895 };
896
897 tag: u32,
898 scope: Builder.Metadata,
899 entity: Builder.Metadata,
900 line: u32,
901 name: Builder.MetadataString,
902 file: Builder.Metadata,
903 };
904
882905 pub const SubroutineType = struct {
883906 pub const ops = [_]AbbrevOp{
884907 .{ .literal = 19 },