authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-21 00:19:52-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-21 00:19:52-07:00
log397be0c9cc8156d38d1487a4c80210007033cbd0
treed34820b5591b79d7f9cd71f2b671fdbfc7c9e3dc
parent18d412ab2fb7bda92f7bfbdf732849bbcd066c33
parent94cf4d2d8193efb0ae642d475fb8437eb4c7e8c1
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20380 from tau-dev/master

llvm: Nest debug info correctly

5 files changed, 716 insertions(+), 483 deletions(-)

lib/std/debug.zig+12-1
......@@ -2459,13 +2459,24 @@ pub const ModuleDebugInfo = switch (native_os) {
24592459 module,
24602460 relocated_address - coff_section.virtual_address,
24612461 ) orelse "???";
2462 // While DWARF gets us just the function's own name, the PDB
2463 // stores it qualified with its namespace by the C++ `::`
2464 // operator. We can strip that for consistency; the
2465 // SymbolInfo will contain the line number, which is a more
2466 // language-neutral way of distinguishing same-named symbols
2467 // anyway.
2468 const symbol_simple_name = if (mem.indexOf(u8, symbol_name, "::")) |cpp_namespace|
2469 symbol_name[cpp_namespace + 2 ..]
2470 else
2471 symbol_name;
2472
24622473 const opt_line_info = try self.pdb.?.getLineNumberInfo(
24632474 module,
24642475 relocated_address - coff_section.virtual_address,
24652476 );
24662477
24672478 return SymbolInfo{
2468 .symbol_name = symbol_name,
2479 .symbol_name = symbol_simple_name,
24692480 .compile_unit_name = obj_basename,
24702481 .line_info = opt_line_info,
24712482 };
src/codegen/llvm.zig+504-457
......@@ -805,14 +805,17 @@ pub const Object = struct {
805805
806806 debug_enums_fwd_ref: Builder.Metadata,
807807 debug_globals_fwd_ref: Builder.Metadata,
808 debug_imports_fwd_ref: Builder.Metadata,
808809
809810 debug_enums: std.ArrayListUnmanaged(Builder.Metadata),
810811 debug_globals: std.ArrayListUnmanaged(Builder.Metadata),
812 debug_imports: std.ArrayListUnmanaged(Builder.Metadata),
811813
812814 debug_file_map: std.AutoHashMapUnmanaged(*const Zcu.File, Builder.Metadata),
813815 debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata),
814816
815 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),
817 // The value says whether this namespace's type is runtime-required.
818 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(Type, bool),
816819
817820 target: std.Target,
818821 /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,
......@@ -877,7 +880,7 @@ pub const Object = struct {
877880
878881 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }});
879882
880 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref =
883 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref, const debug_imports_fwd_ref =
881884 if (!builder.strip)
882885 debug_info: {
883886 // We fully resolve all paths at this point to avoid lack of
......@@ -909,6 +912,7 @@ pub const Object = struct {
909912
910913 const debug_enums_fwd_ref = try builder.debugForwardReference();
911914 const debug_globals_fwd_ref = try builder.debugForwardReference();
915 const debug_imports_fwd_ref = try builder.debugForwardReference();
912916
913917 const debug_compile_unit = try builder.debugCompileUnit(
914918 debug_file,
......@@ -921,6 +925,7 @@ pub const Object = struct {
921925 }),
922926 debug_enums_fwd_ref,
923927 debug_globals_fwd_ref,
928 debug_imports_fwd_ref,
924929 .{ .optimized = comp.root_mod.optimize_mode != .Debug },
925930 );
926931
......@@ -976,8 +981,8 @@ pub const Object = struct {
976981 }
977982
978983 try builder.debugNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit});
979 break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref };
980 } else .{.none} ** 3;
984 break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref, debug_imports_fwd_ref };
985 } else .{.none} ** 4;
981986
982987 const obj = try arena.create(Object);
983988 obj.* = .{
......@@ -990,8 +995,10 @@ pub const Object = struct {
990995 .debug_compile_unit = debug_compile_unit,
991996 .debug_enums_fwd_ref = debug_enums_fwd_ref,
992997 .debug_globals_fwd_ref = debug_globals_fwd_ref,
998 .debug_imports_fwd_ref = debug_imports_fwd_ref,
993999 .debug_enums = .{},
9941000 .debug_globals = .{},
1001 .debug_imports = .{},
9951002 .debug_file_map = .{},
9961003 .debug_type_map = .{},
9971004 .debug_unresolved_namespace_scopes = .{},
......@@ -1133,18 +1140,7 @@ pub const Object = struct {
11331140 try self.genModuleLevelAssembly();
11341141
11351142 if (!self.builder.strip) {
1136 {
1137 var i: usize = 0;
1138 while (i < self.debug_unresolved_namespace_scopes.count()) : (i += 1) {
1139 const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i];
1140 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
1141
1142 const namespace = zcu.namespacePtr(namespace_index);
1143 const debug_type = try self.lowerDebugType(namespace.getType(zcu));
1144
1145 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
1146 }
1147 }
1143 try self.genNamespaces();
11481144
11491145 self.builder.debugForwardReferenceSetType(
11501146 self.debug_enums_fwd_ref,
......@@ -1155,6 +1151,11 @@ pub const Object = struct {
11551151 self.debug_globals_fwd_ref,
11561152 try self.builder.debugTuple(self.debug_globals.items),
11571153 );
1154
1155 self.builder.debugForwardReferenceSetType(
1156 self.debug_imports_fwd_ref,
1157 try self.builder.debugTuple(self.debug_imports.items),
1158 );
11581159 }
11591160 }
11601161
......@@ -1634,15 +1635,19 @@ pub const Object = struct {
16341635
16351636 const file, const subprogram = if (!wip.strip) debug_info: {
16361637 const file = try o.getDebugFile(file_scope);
1638 const scope = try o.lowerDebugType(zcu.declPtr(namespace.decl_index).val.toType(), false);
16371639
16381640 const line_number = decl.navSrcLine(zcu) + 1;
16391641 const is_internal_linkage = decl.val.getExternFunc(zcu) == null;
1640 const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu));
1642 const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu), true);
1643 const decl_name = try o.builder.metadataString(decl.name.toSlice(ip));
1644 const link_name = try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder));
16411645
16421646 const subprogram = try o.builder.debugSubprogram(
16431647 file,
1644 try o.builder.metadataString(decl.name.toSlice(ip)),
1645 try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)),
1648 scope,
1649 decl_name,
1650 link_name,
16461651 line_number,
16471652 line_number + func.lbrace_line,
16481653 debug_decl_type,
......@@ -1659,6 +1664,7 @@ pub const Object = struct {
16591664 },
16601665 o.debug_compile_unit,
16611666 );
1667
16621668 function_index.setSubprogram(subprogram, &o.builder);
16631669 break :debug_info .{ file, subprogram };
16641670 } else .{.none} ** 2;
......@@ -1906,6 +1912,7 @@ pub const Object = struct {
19061912 pub fn lowerDebugType(
19071913 o: *Object,
19081914 ty: Type,
1915 required_by_runtime: bool,
19091916 ) Allocator.Error!Builder.Metadata {
19101917 assert(!o.builder.strip);
19111918
......@@ -1915,7 +1922,13 @@ pub const Object = struct {
19151922 const zcu = pt.zcu;
19161923 const ip = &zcu.intern_pool;
19171924
1918 if (o.debug_type_map.get(ty)) |debug_type| return debug_type;
1925 if (o.debug_type_map.get(ty)) |debug_type| {
1926 if (required_by_runtime) {
1927 if (o.debug_unresolved_namespace_scopes.getEntry(ty)) |entry|
1928 entry.value_ptr.* = true;
1929 }
1930 return debug_type;
1931 }
19191932
19201933 switch (ty.zigTypeTag(zcu)) {
19211934 .Void,
......@@ -1930,10 +1943,9 @@ pub const Object = struct {
19301943 },
19311944 .Int => {
19321945 const info = ty.intInfo(zcu);
1933 assert(info.bits != 0);
1934 const name = try o.allocTypeName(ty);
1935 defer gpa.free(name);
1936 const builder_name = try o.builder.metadataString(name);
1946 const int_name = try o.allocTypeName(ty);
1947 defer gpa.free(int_name);
1948 const builder_name = try o.builder.metadataString(int_name);
19371949 const debug_bits = ty.abiSize(pt) * 8; // lldb cannot handle non-byte sized types
19381950 const debug_int_type = switch (info.signedness) {
19391951 .signed => try o.builder.debugSignedType(builder_name, debug_bits),
......@@ -1942,68 +1954,12 @@ pub const Object = struct {
19421954 try o.debug_type_map.put(gpa, ty, debug_int_type);
19431955 return debug_int_type;
19441956 },
1945 .Enum => {
1946 const owner_decl_index = ty.getOwnerDecl(zcu);
1947 const owner_decl = zcu.declPtr(owner_decl_index);
1948
1949 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
1950 const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
1951 try o.debug_type_map.put(gpa, ty, debug_enum_type);
1952 return debug_enum_type;
1953 }
1954
1955 const enum_type = ip.loadEnumType(ty.toIntern());
1956
1957 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
1958 defer gpa.free(enumerators);
1959
1960 const int_ty = Type.fromInterned(enum_type.tag_ty);
1961 const int_info = ty.intInfo(zcu);
1962 assert(int_info.bits != 0);
1963
1964 for (enum_type.names.get(ip), 0..) |field_name_ip, i| {
1965 var bigint_space: Value.BigIntSpace = undefined;
1966 const bigint = if (enum_type.values.len != 0)
1967 Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt)
1968 else
1969 std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst();
1970
1971 enumerators[i] = try o.builder.debugEnumerator(
1972 try o.builder.metadataString(field_name_ip.toSlice(ip)),
1973 int_info.signedness == .unsigned,
1974 int_info.bits,
1975 bigint,
1976 );
1977 }
1978
1979 const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu);
1980 const file = try o.getDebugFile(file_scope);
1981 const scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
1982
1983 const name = try o.allocTypeName(ty);
1984 defer gpa.free(name);
1985
1986 const debug_enum_type = try o.builder.debugEnumerationType(
1987 try o.builder.metadataString(name),
1988 file,
1989 scope,
1990 owner_decl.typeSrcLine(zcu) + 1, // Line
1991 try o.lowerDebugType(int_ty),
1992 ty.abiSize(pt) * 8,
1993 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
1994 try o.builder.debugTuple(enumerators),
1995 );
1996
1997 try o.debug_type_map.put(gpa, ty, debug_enum_type);
1998 try o.debug_enums.append(gpa, debug_enum_type);
1999 return debug_enum_type;
2000 },
20011957 .Float => {
20021958 const bits = ty.floatBits(target);
2003 const name = try o.allocTypeName(ty);
2004 defer gpa.free(name);
1959 const float_name = try o.allocTypeName(ty);
1960 defer gpa.free(float_name);
20051961 const debug_float_type = try o.builder.debugFloatType(
2006 try o.builder.metadataString(name),
1962 try o.builder.metadataString(float_name),
20071963 bits,
20081964 );
20091965 try o.debug_type_map.put(gpa, ty, debug_float_type);
......@@ -2045,7 +2001,7 @@ pub const Object = struct {
20452001 },
20462002 },
20472003 });
2048 const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty);
2004 const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty, required_by_runtime);
20492005 try o.debug_type_map.put(gpa, ty, debug_ptr_type);
20502006 return debug_ptr_type;
20512007 }
......@@ -2061,6 +2017,7 @@ pub const Object = struct {
20612017
20622018 const name = try o.allocTypeName(ty);
20632019 defer gpa.free(name);
2020
20642021 const line = 0;
20652022
20662023 const ptr_size = ptr_ty.abiSize(pt);
......@@ -2075,7 +2032,7 @@ pub const Object = struct {
20752032 .none, // File
20762033 debug_fwd_ref,
20772034 0, // Line
2078 try o.lowerDebugType(ptr_ty),
2035 try o.lowerDebugType(ptr_ty, required_by_runtime),
20792036 ptr_size * 8,
20802037 (ptr_align.toByteUnits() orelse 0) * 8,
20812038 0, // Offset
......@@ -2086,7 +2043,7 @@ pub const Object = struct {
20862043 .none, // File
20872044 debug_fwd_ref,
20882045 0, // Line
2089 try o.lowerDebugType(len_ty),
2046 try o.lowerDebugType(len_ty, required_by_runtime),
20902047 len_size * 8,
20912048 (len_align.toByteUnits() orelse 0) * 8,
20922049 len_offset * 8,
......@@ -2104,6 +2061,7 @@ pub const Object = struct {
21042061 debug_ptr_type,
21052062 debug_len_type,
21062063 }),
2064 isByRef(ty, pt),
21072065 );
21082066
21092067 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_slice_type);
......@@ -2115,7 +2073,7 @@ pub const Object = struct {
21152073 return debug_slice_type;
21162074 }
21172075
2118 const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child));
2076 const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child), required_by_runtime);
21192077
21202078 const name = try o.allocTypeName(ty);
21212079 defer gpa.free(name);
......@@ -2139,41 +2097,13 @@ pub const Object = struct {
21392097
21402098 return debug_ptr_type;
21412099 },
2142 .Opaque => {
2143 if (ty.toIntern() == .anyopaque_type) {
2144 const debug_opaque_type = try o.builder.debugSignedType(
2145 try o.builder.metadataString("anyopaque"),
2146 0,
2147 );
2148 try o.debug_type_map.put(gpa, ty, debug_opaque_type);
2149 return debug_opaque_type;
2150 }
2151
2152 const name = try o.allocTypeName(ty);
2153 defer gpa.free(name);
2154 const owner_decl_index = ty.getOwnerDecl(zcu);
2155 const owner_decl = zcu.declPtr(owner_decl_index);
2156 const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu);
2157 const debug_opaque_type = try o.builder.debugStructType(
2158 try o.builder.metadataString(name),
2159 try o.getDebugFile(file_scope),
2160 try o.namespaceToDebugScope(owner_decl.src_namespace),
2161 owner_decl.typeSrcLine(zcu) + 1, // Line
2162 .none, // Underlying type
2163 0, // Size
2164 0, // Align
2165 .none, // Fields
2166 );
2167 try o.debug_type_map.put(gpa, ty, debug_opaque_type);
2168 return debug_opaque_type;
2169 },
21702100 .Array => {
21712101 const debug_array_type = try o.builder.debugArrayType(
21722102 .none, // Name
21732103 .none, // File
21742104 .none, // Scope
21752105 0, // Line
2176 try o.lowerDebugType(ty.childType(zcu)),
2106 try o.lowerDebugType(ty.childType(zcu), required_by_runtime),
21772107 ty.abiSize(pt) * 8,
21782108 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
21792109 try o.builder.debugTuple(&.{
......@@ -2195,10 +2125,9 @@ pub const Object = struct {
21952125 const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) {
21962126 .Int => blk: {
21972127 const info = elem_ty.intInfo(zcu);
2198 assert(info.bits != 0);
2199 const name = try o.allocTypeName(ty);
2200 defer gpa.free(name);
2201 const builder_name = try o.builder.metadataString(name);
2128 const vec_name = try o.allocTypeName(ty);
2129 defer gpa.free(vec_name);
2130 const builder_name = try o.builder.metadataString(vec_name);
22022131 break :blk switch (info.signedness) {
22032132 .signed => try o.builder.debugSignedType(builder_name, info.bits),
22042133 .unsigned => try o.builder.debugUnsignedType(builder_name, info.bits),
......@@ -2208,7 +2137,7 @@ pub const Object = struct {
22082137 try o.builder.metadataString("bool"),
22092138 1,
22102139 ),
2211 else => try o.lowerDebugType(ty.childType(zcu)),
2140 else => try o.lowerDebugType(ty.childType(zcu), required_by_runtime),
22122141 };
22132142
22142143 const debug_vector_type = try o.builder.debugVectorType(
......@@ -2233,6 +2162,7 @@ pub const Object = struct {
22332162 .Optional => {
22342163 const name = try o.allocTypeName(ty);
22352164 defer gpa.free(name);
2165
22362166 const child_ty = ty.optionalChild(zcu);
22372167 if (!child_ty.hasRuntimeBitsIgnoreComptime(pt)) {
22382168 const debug_bool_type = try o.builder.debugBoolType(
......@@ -2249,7 +2179,7 @@ pub const Object = struct {
22492179 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
22502180
22512181 if (ty.optionalReprIsPayload(zcu)) {
2252 const debug_optional_type = try o.lowerDebugType(child_ty);
2182 const debug_optional_type = try o.lowerDebugType(child_ty, required_by_runtime);
22532183
22542184 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type);
22552185
......@@ -2272,7 +2202,7 @@ pub const Object = struct {
22722202 .none, // File
22732203 debug_fwd_ref,
22742204 0, // Line
2275 try o.lowerDebugType(child_ty),
2205 try o.lowerDebugType(child_ty, required_by_runtime),
22762206 payload_size * 8,
22772207 (payload_align.toByteUnits() orelse 0) * 8,
22782208 0, // Offset
......@@ -2283,7 +2213,7 @@ pub const Object = struct {
22832213 .none,
22842214 debug_fwd_ref,
22852215 0,
2286 try o.lowerDebugType(non_null_ty),
2216 try o.lowerDebugType(non_null_ty, required_by_runtime),
22872217 non_null_size * 8,
22882218 (non_null_align.toByteUnits() orelse 0) * 8,
22892219 non_null_offset * 8,
......@@ -2301,6 +2231,7 @@ pub const Object = struct {
23012231 debug_data_type,
23022232 debug_some_type,
23032233 }),
2234 isByRef(ty, pt),
23042235 );
23052236
23062237 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type);
......@@ -2315,7 +2246,7 @@ pub const Object = struct {
23152246 const payload_ty = ty.errorUnionPayload(zcu);
23162247 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
23172248 // TODO: Maybe remove?
2318 const debug_error_union_type = try o.lowerDebugType(Type.anyerror);
2249 const debug_error_union_type = try o.lowerDebugType(Type.anyerror, required_by_runtime);
23192250 try o.debug_type_map.put(gpa, ty, debug_error_union_type);
23202251 return debug_error_union_type;
23212252 }
......@@ -2352,7 +2283,7 @@ pub const Object = struct {
23522283 .none, // File
23532284 debug_fwd_ref,
23542285 0, // Line
2355 try o.lowerDebugType(Type.anyerror),
2286 try o.lowerDebugType(Type.anyerror, required_by_runtime),
23562287 error_size * 8,
23572288 (error_align.toByteUnits() orelse 0) * 8,
23582289 error_offset * 8,
......@@ -2362,7 +2293,7 @@ pub const Object = struct {
23622293 .none, // File
23632294 debug_fwd_ref,
23642295 0, // Line
2365 try o.lowerDebugType(payload_ty),
2296 try o.lowerDebugType(payload_ty, required_by_runtime),
23662297 payload_size * 8,
23672298 (payload_align.toByteUnits() orelse 0) * 8,
23682299 payload_offset * 8,
......@@ -2377,6 +2308,7 @@ pub const Object = struct {
23772308 ty.abiSize(pt) * 8,
23782309 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
23792310 try o.builder.debugTuple(&fields),
2311 isByRef(ty, pt),
23802312 );
23812313
23822314 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_error_union_type);
......@@ -2392,383 +2324,483 @@ pub const Object = struct {
23922324 try o.debug_type_map.put(gpa, ty, debug_error_set);
23932325 return debug_error_set;
23942326 },
2395 .Struct => {
2396 const name = try o.allocTypeName(ty);
2397 defer gpa.free(name);
2327 .Fn => {
2328 const fn_info = zcu.typeToFunc(ty).?;
23982329
2399 if (zcu.typeToPackedStruct(ty)) |struct_type| {
2400 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);
2401 if (backing_int_ty != .none) {
2402 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);
2403 const builder_name = try o.builder.metadataString(name);
2404 const debug_int_type = switch (info.signedness) {
2405 .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8),
2406 .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8),
2407 };
2408 try o.debug_type_map.put(gpa, ty, debug_int_type);
2409 return debug_int_type;
2410 }
2411 }
2330 var debug_param_types = std.ArrayList(Builder.Metadata).init(gpa);
2331 defer debug_param_types.deinit();
24122332
2413 switch (ip.indexToKey(ty.toIntern())) {
2414 .anon_struct_type => |tuple| {
2415 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2416 defer fields.deinit(gpa);
2417
2418 try fields.ensureUnusedCapacity(gpa, tuple.types.len);
2419
2420 comptime assert(struct_layout_version == 2);
2421 var offset: u64 = 0;
2422
2423 const debug_fwd_ref = try o.builder.debugForwardReference();
2424
2425 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
2426 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
2427
2428 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2429 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
2430 const field_offset = field_align.forward(offset);
2431 offset = field_offset + field_size;
2432
2433 const field_name = if (tuple.names.len != 0)
2434 tuple.names.get(ip)[i].toSlice(ip)
2435 else
2436 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
2437 defer if (tuple.names.len == 0) gpa.free(field_name);
2438
2439 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2440 try o.builder.metadataString(field_name),
2441 .none, // File
2442 debug_fwd_ref,
2443 0,
2444 try o.lowerDebugType(Type.fromInterned(field_ty)),
2445 field_size * 8,
2446 (field_align.toByteUnits() orelse 0) * 8,
2447 field_offset * 8,
2448 ));
2449 }
2333 try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len);
24502334
2451 const debug_struct_type = try o.builder.debugStructType(
2452 try o.builder.metadataString(name),
2453 .none, // File
2454 o.debug_compile_unit, // Scope
2455 0, // Line
2456 .none, // Underlying type
2457 ty.abiSize(pt) * 8,
2458 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2459 try o.builder.debugTuple(fields.items),
2460 );
2335 // Return type goes first.
2336 if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) {
2337 const sret = firstParamSRet(fn_info, pt, target);
2338 const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);
2339 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty, required_by_runtime));
24612340
2462 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type);
2341 if (sret) {
2342 const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type));
2343 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
2344 }
2345 } else {
2346 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void, required_by_runtime));
2347 }
24632348
2464 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2465 return debug_struct_type;
2466 },
2467 .struct_type => {
2468 if (!ip.loadStructType(ty.toIntern()).haveFieldTypes(ip)) {
2469 // This can happen if a struct type makes it all the way to
2470 // flush() without ever being instantiated or referenced (even
2471 // via pointer). The only reason we are hearing about it now is
2472 // that it is being used as a namespace to put other debug types
2473 // into. Therefore we can satisfy this by making an empty namespace,
2474 // rather than changing the frontend to unnecessarily resolve the
2475 // struct field types.
2476 const owner_decl_index = ty.getOwnerDecl(zcu);
2477 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2478 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2479 return debug_struct_type;
2480 }
2481 },
2482 else => {},
2349 if (Type.fromInterned(fn_info.return_type).isError(zcu) and
2350 zcu.comp.config.any_error_tracing)
2351 {
2352 const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType());
2353 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
24832354 }
24842355
2485 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2486 const owner_decl_index = ty.getOwnerDecl(zcu);
2487 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2488 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2489 return debug_struct_type;
2356 for (0..fn_info.param_types.len) |i| {
2357 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]);
2358 if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
2359
2360 if (isByRef(param_ty, pt)) {
2361 const ptr_ty = try pt.singleMutPtrType(param_ty);
2362 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
2363 } else {
2364 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty, required_by_runtime));
2365 }
24902366 }
24912367
2492 const struct_type = zcu.typeToStruct(ty).?;
2368 const debug_function_type = try o.builder.debugSubroutineType(
2369 try o.builder.debugTuple(debug_param_types.items),
2370 );
24932371
2494 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2495 defer fields.deinit(gpa);
2372 try o.debug_type_map.put(gpa, ty, debug_function_type);
2373 return debug_function_type;
2374 },
2375 .ComptimeInt => unreachable,
2376 .ComptimeFloat => unreachable,
2377 .Type => unreachable,
2378 .Undefined => unreachable,
2379 .Null => unreachable,
2380 .EnumLiteral => unreachable,
24962381
2497 try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
2382 .Frame => @panic("TODO implement lowerDebugType for Frame types"),
2383 .AnyFrame => @panic("TODO implement lowerDebugType for AnyFrame types"),
2384 // These are the types that need a correct scope.
2385 .Enum, .Struct, .Union, .Opaque => {},
2386 }
2387 const fwd_ref = try o.builder.debugForwardReference();
2388 try o.debug_type_map.put(gpa, ty, fwd_ref);
2389 try o.debug_unresolved_namespace_scopes.put(gpa, ty, required_by_runtime);
24982390
2499 const debug_fwd_ref = try o.builder.debugForwardReference();
2391 return fwd_ref;
2392 }
25002393
2501 // Set as forward reference while the type is lowered in case it references itself
2502 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
2394 fn genNamespaces(o: *Object) !void {
2395 const gpa = o.gpa;
2396 const pt = o.pt;
2397 const zcu = pt.zcu;
2398 const ip = &zcu.intern_pool;
25032399
2504 comptime assert(struct_layout_version == 2);
2505 var it = struct_type.iterateRuntimeOrder(ip);
2506 while (it.next()) |field_index| {
2507 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2508 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
2509 const field_size = field_ty.abiSize(pt);
2510 const field_align = pt.structFieldAlignment(
2511 struct_type.fieldAlign(ip, field_index),
2512 field_ty,
2513 struct_type.layout,
2514 );
2515 const field_offset = ty.structFieldOffset(field_index, pt);
2400 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2401 defer fields.deinit(gpa);
25162402
2517 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
2518 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
2403 const unresolved = &o.debug_unresolved_namespace_scopes;
2404 var unresolved_i: usize = 0;
2405 while (unresolved_i < unresolved.count()) : (unresolved_i += 1) {
2406 const ty = unresolved.keys()[unresolved_i];
2407 const required_by_runtime = unresolved.values()[unresolved_i];
25192408
2520 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2521 try o.builder.metadataString(field_name.toSlice(ip)),
2522 .none, // File
2523 debug_fwd_ref,
2524 0, // Line
2525 try o.lowerDebugType(field_ty),
2526 field_size * 8,
2527 (field_align.toByteUnits() orelse 0) * 8,
2528 field_offset * 8,
2529 ));
2530 }
2409 const owner_decl_index = ty.getOwnerDeclOrNull(zcu);
2410 const owner_decl: ?*Zcu.Decl =
2411 if (owner_decl_index) |owner| ip.declPtr(owner) else null;
25312412
2532 const debug_struct_type = try o.builder.debugStructType(
2533 try o.builder.metadataString(name),
2534 .none, // File
2535 o.debug_compile_unit, // Scope
2536 0, // Line
2537 .none, // Underlying type
2538 ty.abiSize(pt) * 8,
2539 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2540 try o.builder.debugTuple(fields.items),
2541 );
2413 const file = if (owner_decl) |owner|
2414 try o.getDebugFile(zcu.namespacePtr(owner.src_namespace).fileScope(zcu))
2415 else
2416 .none;
2417 const scope = if (owner_decl) |owner|
2418 try o.namespaceToDebugScope(owner.src_namespace)
2419 else
2420 o.debug_compile_unit;
2421 const line = if (owner_decl) |owner| owner.typeSrcLine(zcu) + 1 else 0;
25422422
2543 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type);
2423 const name = if (owner_decl) |owner| owner.name.toSlice(ip) else try o.allocTypeName(ty);
2424 defer if (owner_decl == null) gpa.free(name);
25442425
2545 // Set to real type now that it has been lowered fully
2546 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2547 map_ptr.* = debug_struct_type;
2426 const fwd_ref = o.debug_type_map.get(ty).?;
25482427
2549 return debug_struct_type;
2550 },
2551 .Union => {
2552 const owner_decl_index = ty.getOwnerDecl(zcu);
2428 fields.clearRetainingCapacity();
25532429
2554 const name = try o.allocTypeName(ty);
2555 defer gpa.free(name);
2430 const ns = if (ty.getNamespace(zcu)) |n| n.unwrap() else null;
2431 if (ns) |ns_id| {
2432 const namespace = ip.namespacePtr(ns_id);
2433 try fields.ensureUnusedCapacity(gpa, namespace.decls.keys().len);
25562434
2557 const union_type = ip.loadUnionType(ty.toIntern());
2558 if (!union_type.haveFieldTypes(ip) or
2559 !ty.hasRuntimeBitsIgnoreComptime(pt) or
2560 !union_type.haveLayout(ip))
2561 {
2562 const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2563 try o.debug_type_map.put(gpa, ty, debug_union_type);
2564 return debug_union_type;
2435 for (namespace.decls.keys()) |decl_id| {
2436 const decl = ip.declPtr(decl_id);
2437 const decl_name = decl.name.toSlice(ip);
2438
2439 if (!decl.has_tv) continue;
2440 if (decl.kind != .named) continue;
2441 if (decl.analysis != .complete) continue;
2442
2443 const decl_line = 0;
2444
2445 if (decl.val.typeOf(zcu).ip_index == .type_type) {
2446 const nested_type = decl.val.toType();
2447 // If this decl is the owner of the type, it will
2448 // already have been declared as a direct child and
2449 // will not need to be typedef'd.
2450 if (nested_type.getOwnerDeclOrNull(zcu)) |owner| {
2451 if (owner == decl_id) continue;
2452 }
2453
2454 switch (nested_type.zigTypeTag(zcu)) {
2455 // We still may want these for a Zig expression
2456 // evaluator in debuggers, but for now they are
2457 // completely useless.
2458 .ComptimeInt, .ComptimeFloat, .Type, .Undefined, .Null, .EnumLiteral => continue,
2459 else => {},
2460 }
2461
2462 fields.appendAssumeCapacity(try o.builder.debugTypedef(
2463 try o.builder.metadataString(decl_name),
2464 try o.getDebugFile(namespace.fileScope(zcu)),
2465 fwd_ref,
2466 decl_line,
2467 try o.lowerDebugType(nested_type, false),
2468 0, // Align
2469 ));
2470 }
25652471 }
2472 }
25662473
2567 const layout = pt.getUnionLayout(union_type);
2474 if (!required_by_runtime) {
2475 const res = try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2476 o.builder.debugForwardReferenceSetType(fwd_ref, res);
2477 continue;
2478 }
25682479
2569 const debug_fwd_ref = try o.builder.debugForwardReference();
2480 const res = switch (ty.zigTypeTag(zcu)) {
2481 .Enum => res: {
2482 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2483 break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2484 }
25702485
2571 // Set as forward reference while the type is lowered in case it references itself
2572 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
2486 const enum_type = ip.loadEnumType(ty.toIntern());
2487
2488 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
2489 defer gpa.free(enumerators);
2490
2491 const int_ty = Type.fromInterned(enum_type.tag_ty);
2492 const int_info = ty.intInfo(zcu);
2493 assert(int_info.bits != 0);
2494
2495 for (enum_type.names.get(ip), 0..) |field_name_ip, i| {
2496 var bigint_space: Value.BigIntSpace = undefined;
2497 const bigint = if (enum_type.values.len != 0)
2498 Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt)
2499 else
2500 std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst();
2501
2502 enumerators[i] = try o.builder.debugEnumerator(
2503 try o.builder.metadataString(field_name_ip.toSlice(ip)),
2504 int_info.signedness == .unsigned,
2505 int_info.bits,
2506 bigint,
2507 );
2508 }
25732509
2574 if (layout.payload_size == 0) {
2575 const debug_union_type = try o.builder.debugStructType(
2510 const debug_enum_type = try o.builder.debugEnumerationType(
25762511 try o.builder.metadataString(name),
2577 .none, // File
2578 o.debug_compile_unit, // Scope
2579 0, // Line
2580 .none, // Underlying type
2512 file,
2513 scope,
2514 line,
2515 try o.lowerDebugType(int_ty, required_by_runtime),
25812516 ty.abiSize(pt) * 8,
25822517 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2583 try o.builder.debugTuple(
2584 &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))},
2585 ),
2518 try o.builder.debugTuple(enumerators),
25862519 );
25872520
2588 // Set to real type now that it has been lowered fully
2589 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2590 map_ptr.* = debug_union_type;
2591
2592 return debug_union_type;
2593 }
2521 try o.debug_enums.append(gpa, debug_enum_type);
2522 break :res debug_enum_type;
2523 },
2524 .Opaque => res: {
2525 if (ty.toIntern() == .anyopaque_type) {
2526 break :res try o.builder.debugSignedType(
2527 try o.builder.metadataString("anyopaque"),
2528 0,
2529 );
2530 }
25942531
2595 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2596 defer fields.deinit(gpa);
2532 const debug_opaque_type = try o.builder.debugStructType(
2533 try o.builder.metadataString(name),
2534 file,
2535 scope,
2536 line,
2537 .none, // Underlying type
2538 0, // Size
2539 0, // Align
2540 .none, // Fields
2541 false, // ByRef
2542 );
2543 break :res debug_opaque_type;
2544 },
2545 .Struct => res: {
2546 if (zcu.typeToPackedStruct(ty)) |struct_type| {
2547 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);
2548 if (backing_int_ty != .none) {
2549 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);
2550 const builder_name = try o.builder.metadataString(name);
2551 const debug_int_type = switch (info.signedness) {
2552 .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8),
2553 .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8),
2554 };
2555 break :res debug_int_type;
2556 }
2557 }
25972558
2598 try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len);
2559 switch (ip.indexToKey(ty.toIntern())) {
2560 .anon_struct_type => |tuple| {
2561 try fields.ensureUnusedCapacity(gpa, tuple.types.len);
2562
2563 comptime assert(struct_layout_version == 2);
2564 var offset: u64 = 0;
2565
2566 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
2567 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
2568
2569 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2570 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
2571 const field_offset = field_align.forward(offset);
2572 offset = field_offset + field_size;
2573
2574 const field_name = if (tuple.names.len != 0)
2575 tuple.names.get(ip)[i].toSlice(ip)
2576 else
2577 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
2578 defer if (tuple.names.len == 0) gpa.free(field_name);
2579
2580 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2581 try o.builder.metadataString(field_name),
2582 .none, // File
2583 fwd_ref,
2584 0,
2585 try o.lowerDebugType(Type.fromInterned(field_ty), required_by_runtime),
2586 field_size * 8,
2587 (field_align.toByteUnits() orelse 0) * 8,
2588 field_offset * 8,
2589 ));
2590 }
25992591
2600 const debug_union_fwd_ref = if (layout.tag_size == 0)
2601 debug_fwd_ref
2602 else
2603 try o.builder.debugForwardReference();
2592 const debug_struct_type = try o.builder.debugStructType(
2593 try o.builder.metadataString(name),
2594 file,
2595 scope,
2596 0, // Line
2597 .none, // Underlying type
2598 ty.abiSize(pt) * 8,
2599 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2600 try o.builder.debugTuple(fields.items),
2601 isByRef(ty, pt),
2602 );
26042603
2605 const tag_type = union_type.loadTagType(ip);
2604 break :res debug_struct_type;
2605 },
2606 else => {},
2607 }
26062608
2607 for (0..tag_type.names.len) |field_index| {
2608 const field_ty = union_type.field_types.get(ip)[field_index];
2609 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
2609 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2610 break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2611 }
2612 const struct_type = zcu.typeToStruct(ty).?;
26102613
2611 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2612 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {
2613 .@"packed" => .none,
2614 .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)),
2615 };
2614 if (!struct_type.haveLayout(ip) or !struct_type.haveFieldTypes(ip)) {
2615 break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
2616 }
26162617
2617 const field_name = tag_type.names.get(ip)[field_index];
2618 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2619 try o.builder.metadataString(field_name.toSlice(ip)),
2620 .none, // File
2621 debug_union_fwd_ref,
2622 0, // Line
2623 try o.lowerDebugType(Type.fromInterned(field_ty)),
2624 field_size * 8,
2625 (field_align.toByteUnits() orelse 0) * 8,
2626 0, // Offset
2627 ));
2628 }
2618 try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
26292619
2630 var union_name_buf: ?[:0]const u8 = null;
2631 defer if (union_name_buf) |buf| gpa.free(buf);
2632 const union_name = if (layout.tag_size == 0) name else name: {
2633 union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name});
2634 break :name union_name_buf.?;
2635 };
2620 comptime assert(struct_layout_version == 2);
2621 var it = struct_type.iterateRuntimeOrder(ip);
2622 while (it.next()) |field_index| {
2623 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2624 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
2625 const field_size = field_ty.abiSize(pt);
2626 const field_align = pt.structFieldAlignment(
2627 struct_type.fieldAlign(ip, field_index),
2628 field_ty,
2629 struct_type.layout,
2630 );
2631 const field_offset = ty.structFieldOffset(field_index, pt);
26362632
2637 const debug_union_type = try o.builder.debugUnionType(
2638 try o.builder.metadataString(union_name),
2639 .none, // File
2640 o.debug_compile_unit, // Scope
2641 0, // Line
2642 .none, // Underlying type
2643 ty.abiSize(pt) * 8,
2644 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2645 try o.builder.debugTuple(fields.items),
2646 );
2633 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
2634 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
26472635
2648 o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type);
2636 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2637 try o.builder.metadataString(field_name.toSlice(ip)),
2638 file,
2639 fwd_ref,
2640 0, // Line
2641 try o.lowerDebugType(field_ty, required_by_runtime),
2642 field_size * 8,
2643 (field_align.toByteUnits() orelse 0) * 8,
2644 field_offset * 8,
2645 ));
2646 }
26492647
2650 if (layout.tag_size == 0) {
2651 // Set to real type now that it has been lowered fully
2652 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2653 map_ptr.* = debug_union_type;
2648 const debug_struct_type = try o.builder.debugStructType(
2649 try o.builder.metadataString(name),
2650 file,
2651 scope,
2652 line,
2653 .none, // Underlying type
2654 ty.abiSize(pt) * 8,
2655 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2656 try o.builder.debugTuple(fields.items),
2657 isByRef(ty, pt),
2658 );
26542659
2655 return debug_union_type;
2656 }
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 }
26572670
2658 var tag_offset: u64 = undefined;
2659 var payload_offset: u64 = undefined;
2660 if (layout.tag_align.compare(.gte, layout.payload_align)) {
2661 tag_offset = 0;
2662 payload_offset = layout.payload_align.forward(layout.tag_size);
2663 } else {
2664 payload_offset = 0;
2665 tag_offset = layout.tag_align.forward(layout.payload_size);
2666 }
2671 const layout = pt.getUnionLayout(union_type);
26672672
2668 const debug_tag_type = try o.builder.debugMemberType(
2669 try o.builder.metadataString("tag"),
2670 .none, // File
2671 debug_fwd_ref,
2672 0, // Line
2673 try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty)),
2674 layout.tag_size * 8,
2675 (layout.tag_align.toByteUnits() orelse 0) * 8,
2676 tag_offset * 8,
2677 );
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 isByRef(ty, pt),
2686 );
26782687
2679 const debug_payload_type = try o.builder.debugMemberType(
2680 try o.builder.metadataString("payload"),
2681 .none, // File
2682 debug_fwd_ref,
2683 0, // Line
2684 debug_union_type,
2685 layout.payload_size * 8,
2686 (layout.payload_align.toByteUnits() orelse 0) * 8,
2687 payload_offset * 8,
2688 );
2688 break :res debug_union_type;
2689 }
26892690
2690 const full_fields: [2]Builder.Metadata =
2691 if (layout.tag_align.compare(.gte, layout.payload_align))
2692 .{ debug_tag_type, debug_payload_type }
2693 else
2694 .{ debug_payload_type, debug_tag_type };
2691 try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len);
26952692
2696 const debug_tagged_union_type = try o.builder.debugStructType(
2697 try o.builder.metadataString(name),
2698 .none, // File
2699 o.debug_compile_unit, // Scope
2700 0, // Line
2701 .none, // Underlying type
2702 ty.abiSize(pt) * 8,
2703 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2704 try o.builder.debugTuple(&full_fields),
2705 );
2693 const debug_union_fwd_ref = if (layout.tag_size == 0)
2694 fwd_ref
2695 else
2696 try o.builder.debugForwardReference();
27062697
2707 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_tagged_union_type);
2698 const tag_type = union_type.loadTagType(ip);
27082699
2709 // Set to real type now that it has been lowered fully
2710 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2711 map_ptr.* = debug_tagged_union_type;
2700 for (0..tag_type.names.len) |field_index| {
2701 const field_ty = union_type.field_types.get(ip)[field_index];
2702 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
27122703
2713 return debug_tagged_union_type;
2714 },
2715 .Fn => {
2716 const fn_info = zcu.typeToFunc(ty).?;
2704 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2705 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {
2706 .@"packed" => .none,
2707 .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)),
2708 };
27172709
2718 var debug_param_types = std.ArrayList(Builder.Metadata).init(gpa);
2719 defer debug_param_types.deinit();
2710 const field_name = tag_type.names.get(ip)[field_index];
2711 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2712 try o.builder.metadataString(field_name.toSlice(ip)),
2713 file,
2714 debug_union_fwd_ref,
2715 0, // Line
2716 try o.lowerDebugType(Type.fromInterned(field_ty), required_by_runtime),
2717 field_size * 8,
2718 (field_align.toByteUnits() orelse 0) * 8,
2719 0, // Offset
2720 ));
2721 }
27202722
2721 try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len);
2723 var union_name_buf: ?[:0]const u8 = null;
2724 defer if (union_name_buf) |buf| gpa.free(buf);
2725 const union_name = if (layout.tag_size == 0) name else name: {
2726 union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name});
2727 break :name union_name_buf.?;
2728 };
27222729
2723 // Return type goes first.
2724 if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) {
2725 const sret = firstParamSRet(fn_info, pt, target);
2726 const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);
2727 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty));
2730 const debug_union_type = try o.builder.debugUnionType(
2731 try o.builder.metadataString(union_name),
2732 file,
2733 scope,
2734 line,
2735 .none, // Underlying type
2736 ty.abiSize(pt) * 8,
2737 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2738 try o.builder.debugTuple(fields.items),
2739 isByRef(ty, pt),
2740 );
27282741
2729 if (sret) {
2730 const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type));
2731 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2742 if (layout.tag_size == 0) {
2743 break :res debug_union_type;
27322744 }
2733 } else {
2734 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void));
2735 }
2736
2737 if (Type.fromInterned(fn_info.return_type).isError(zcu) and
2738 zcu.comp.config.any_error_tracing)
2739 {
2740 const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType());
2741 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2742 }
27432745
2744 for (0..fn_info.param_types.len) |i| {
2745 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]);
2746 if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
2746 o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type);
27472747
2748 if (isByRef(param_ty, pt)) {
2749 const ptr_ty = try pt.singleMutPtrType(param_ty);
2750 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2748 var tag_offset: u64 = undefined;
2749 var payload_offset: u64 = undefined;
2750 if (layout.tag_align.compare(.gte, layout.payload_align)) {
2751 tag_offset = 0;
2752 payload_offset = layout.payload_align.forward(layout.tag_size);
27512753 } else {
2752 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty));
2754 payload_offset = 0;
2755 tag_offset = layout.tag_align.forward(layout.payload_size);
27532756 }
2754 }
27552757
2756 const debug_function_type = try o.builder.debugSubroutineType(
2757 try o.builder.debugTuple(debug_param_types.items),
2758 );
2758 const debug_tag_type = try o.builder.debugMemberType(
2759 try o.builder.metadataString("tag"),
2760 file, // File
2761 fwd_ref,
2762 0, // Line
2763 try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty), required_by_runtime),
2764 layout.tag_size * 8,
2765 (layout.tag_align.toByteUnits() orelse 0) * 8,
2766 tag_offset * 8,
2767 );
27592768
2760 try o.debug_type_map.put(gpa, ty, debug_function_type);
2761 return debug_function_type;
2762 },
2763 .ComptimeInt => unreachable,
2764 .ComptimeFloat => unreachable,
2765 .Type => unreachable,
2766 .Undefined => unreachable,
2767 .Null => unreachable,
2768 .EnumLiteral => unreachable,
2769 const debug_payload_type = try o.builder.debugMemberType(
2770 try o.builder.metadataString("payload"),
2771 file,
2772 fwd_ref,
2773 0, // Line
2774 debug_union_type,
2775 layout.payload_size * 8,
2776 (layout.payload_align.toByteUnits() orelse 0) * 8,
2777 payload_offset * 8,
2778 );
27692779
2770 .Frame => @panic("TODO implement lowerDebugType for Frame types"),
2771 .AnyFrame => @panic("TODO implement lowerDebugType for AnyFrame types"),
2780 const full_fields: [2]Builder.Metadata =
2781 if (layout.tag_align.compare(.gte, layout.payload_align))
2782 .{ debug_tag_type, debug_payload_type }
2783 else
2784 .{ debug_payload_type, debug_tag_type };
2785
2786 const debug_tagged_union_type = try o.builder.debugStructType(
2787 try o.builder.metadataString(name),
2788 file, // File
2789 scope,
2790 line,
2791 .none, // Underlying type
2792 ty.abiSize(pt) * 8,
2793 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2794 try o.builder.debugTuple(&full_fields),
2795 isByRef(ty, pt),
2796 );
2797
2798 break :res debug_tagged_union_type;
2799 },
2800 else => unreachable, // Handled above.
2801 };
2802
2803 o.builder.debugForwardReferenceSetType(fwd_ref, res);
27722804 }
27732805 }
27742806
......@@ -2778,14 +2810,10 @@ pub const Object = struct {
27782810 const file_scope = namespace.fileScope(zcu);
27792811 if (namespace.parent == .none) return try o.getDebugFile(file_scope);
27802812
2781 const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index);
2782
2783 if (!gop.found_existing) gop.value_ptr.* = try o.builder.debugForwardReference();
2784
2785 return gop.value_ptr.*;
2813 return o.lowerDebugType(zcu.declPtr(namespace.decl_index).val.toType(), false);
27862814 }
27872815
2788 fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata {
2816 fn makeNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex, fields: []const Builder.Metadata) !Builder.Metadata {
27892817 const zcu = o.pt.zcu;
27902818 const decl = zcu.declPtr(decl_index);
27912819 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
......@@ -2797,7 +2825,8 @@ pub const Object = struct {
27972825 .none,
27982826 0,
27992827 0,
2800 .none,
2828 if (fields.len == 0) .none else try o.builder.debugTuple(fields),
2829 false, // is_byref
28012830 );
28022831 }
28032832
......@@ -4711,16 +4740,33 @@ pub const DeclGen = struct {
47114740 if (!owner_mod.strip) {
47124741 const debug_file = try o.getDebugFile(file_scope);
47134742
4743 const linkage_name = try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder));
4744 const is_internal_linkage = !decl.isExtern(zcu);
4745
4746 const ty = try o.lowerDebugType(decl.typeOf(zcu), true);
47144747 const debug_global_var = try o.builder.debugGlobalVar(
4715 try o.builder.metadataString(decl.name.toSlice(ip)), // Name
4716 try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name
4717 debug_file, // File
4718 debug_file, // Scope
4748 linkage_name,
4749 linkage_name,
4750 debug_file,
4751 debug_file,
47194752 line_number,
4720 try o.lowerDebugType(decl.typeOf(zcu)),
4753 ty,
47214754 variable_index,
4722 .{ .local = !decl.isExtern(zcu) },
4755 is_internal_linkage,
47234756 );
4757 if (is_internal_linkage) {
4758 const name = try o.builder.metadataString(decl.name.toSlice(ip));
4759 const debug_scope = try o.namespaceToDebugScope(decl.src_namespace);
4760
4761 const import = try o.builder.debugImportDeclaration(
4762 name,
4763 debug_file,
4764 debug_scope,
4765 line_number,
4766 debug_global_var,
4767 );
4768 try o.debug_imports.append(o.gpa, import);
4769 }
47244770
47254771 const debug_expression = try o.builder.debugExpression(&.{});
47264772
......@@ -5171,11 +5217,12 @@ pub const FuncGen = struct {
51715217
51725218 self.scope = try o.builder.debugSubprogram(
51735219 self.file,
5220 self.file, // TODO Get the correct scope into here—self.scope is the function's *inner* scope.
51745221 try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)),
51755222 try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)),
51765223 line_number,
51775224 line_number + func.lbrace_line,
5178 try o.lowerDebugType(fn_ty),
5225 try o.lowerDebugType(fn_ty, true),
51795226 .{
51805227 .di_flags = .{ .StaticMember = true },
51815228 .sp_flags = .{
......@@ -6725,7 +6772,7 @@ pub const FuncGen = struct {
67256772 self.file,
67266773 self.scope,
67276774 self.prev_dbg_line,
6728 try o.lowerDebugType(ptr_ty.childType(mod)),
6775 try o.lowerDebugType(ptr_ty.childType(mod), true),
67296776 );
67306777
67316778 _ = try self.wip.callIntrinsic(
......@@ -6758,7 +6805,7 @@ pub const FuncGen = struct {
67586805 self.file,
67596806 self.scope,
67606807 self.prev_dbg_line,
6761 try o.lowerDebugType(operand_ty),
6808 try o.lowerDebugType(operand_ty, true),
67626809 );
67636810
67646811 const pt = o.pt;
......@@ -8872,7 +8919,7 @@ pub const FuncGen = struct {
88728919 self.file,
88738920 self.scope,
88748921 lbrace_line,
8875 try o.lowerDebugType(inst_ty),
8922 try o.lowerDebugType(inst_ty, true),
88768923 @intCast(self.arg_index),
88778924 );
88788925
src/codegen/llvm/Builder.zig+150-22
......@@ -7651,6 +7651,8 @@ pub const Metadata = enum(u32) {
76517651 composite_vector_type,
76527652 derived_pointer_type,
76537653 derived_member_type,
7654 derived_typedef,
7655 imported_declaration,
76547656 subroutine_type,
76557657 enumerator_unsigned,
76567658 enumerator_signed_positive,
......@@ -7696,6 +7698,8 @@ pub const Metadata = enum(u32) {
76967698 .composite_vector_type,
76977699 .derived_pointer_type,
76987700 .derived_member_type,
7701 .derived_typedef,
7702 .imported_declaration,
76997703 .subroutine_type,
77007704 .enumerator_unsigned,
77017705 .enumerator_signed_positive,
......@@ -7812,6 +7816,7 @@ pub const Metadata = enum(u32) {
78127816 producer: MetadataString,
78137817 enums: Metadata,
78147818 globals: Metadata,
7819 imports: Metadata,
78157820 };
78167821
78177822 pub const Subprogram = struct {
......@@ -7860,6 +7865,7 @@ pub const Metadata = enum(u32) {
78607865 }
78617866 };
78627867
7868 scope: Metadata,
78637869 file: Metadata,
78647870 name: MetadataString,
78657871 linkage_name: MetadataString,
......@@ -7905,6 +7911,10 @@ pub const Metadata = enum(u32) {
79057911 align_in_bits_lo: u32,
79067912 align_in_bits_hi: u32,
79077913 fields_tuple: Metadata,
7914 flags: packed struct(u32) {
7915 is_byref: bool,
7916 pad: u31 = 0,
7917 },
79087918
79097919 pub fn bitSize(self: CompositeType) u64 {
79107920 return @as(u64, self.size_in_bits_hi) << 32 | self.size_in_bits_lo;
......@@ -7938,6 +7948,14 @@ pub const Metadata = enum(u32) {
79387948 }
79397949 };
79407950
7951 pub const ImportedEntity = struct {
7952 name: MetadataString,
7953 file: Metadata,
7954 scope: Metadata,
7955 line: u32,
7956 entity: Metadata,
7957 };
7958
79417959 pub const SubroutineType = struct {
79427960 types_tuple: Metadata,
79437961 };
......@@ -7990,10 +8008,6 @@ pub const Metadata = enum(u32) {
79908008 };
79918009
79928010 pub const GlobalVar = struct {
7993 pub const Options = struct {
7994 local: bool,
7995 };
7996
79978011 name: MetadataString,
79988012 linkage_name: MetadataString,
79998013 file: Metadata,
......@@ -8224,6 +8238,7 @@ pub const Metadata = enum(u32) {
82248238 DIBasicType,
82258239 DICompositeType,
82268240 DIDerivedType,
8241 DIImportedEntity,
82278242 DISubroutineType,
82288243 DIEnumerator,
82298244 DISubrange,
......@@ -9961,7 +9976,7 @@ pub fn printUnbuffered(
99619976 .enums = extra.enums,
99629977 .retainedTypes = null,
99639978 .globals = extra.globals,
9964 .imports = null,
9979 .imports = extra.imports,
99659980 .macros = null,
99669981 .dwoId = null,
99679982 .splitDebugInlining = false,
......@@ -9985,7 +10000,7 @@ pub fn printUnbuffered(
998510000 try metadata_formatter.specialized(.@"distinct !", .DISubprogram, .{
998610001 .name = extra.name,
998710002 .linkageName = extra.linkage_name,
9988 .scope = extra.file,
10003 .scope = extra.scope,
998910004 .file = extra.file,
999010005 .line = extra.line,
999110006 .type = extra.ty,
......@@ -10079,8 +10094,8 @@ pub fn printUnbuffered(
1007910094 else => extra.name,
1008010095 },
1008110096 .scope = extra.scope,
10082 .file = null,
10083 .line = null,
10097 .file = extra.file,
10098 .line = extra.line,
1008410099 .baseType = extra.underlying_type,
1008510100 .size = extra.bitSize(),
1008610101 .@"align" = extra.bitAlign(),
......@@ -10101,15 +10116,18 @@ pub fn printUnbuffered(
1010110116 },
1010210117 .derived_pointer_type,
1010310118 .derived_member_type,
10119 .derived_typedef,
1010410120 => |kind| {
1010510121 const extra = self.metadataExtraData(Metadata.DerivedType, metadata_item.data);
1010610122 try metadata_formatter.specialized(.@"!", .DIDerivedType, .{
1010710123 .tag = @as(enum {
1010810124 DW_TAG_pointer_type,
1010910125 DW_TAG_member,
10126 DW_TAG_typedef,
1011010127 }, switch (kind) {
1011110128 .derived_pointer_type => .DW_TAG_pointer_type,
1011210129 .derived_member_type => .DW_TAG_member,
10130 .derived_typedef => .DW_TAG_typedef,
1011310131 else => unreachable,
1011410132 }),
1011510133 .name = switch (extra.name) {
......@@ -10132,6 +10150,22 @@ pub fn printUnbuffered(
1013210150 .annotations = null,
1013310151 }, writer);
1013410152 },
10153 .imported_declaration => {
10154 const extra = self.metadataExtraData(Metadata.ImportedEntity, metadata_item.data);
10155
10156 try metadata_formatter.specialized(.@"!", .DIImportedEntity, .{
10157 .tag = .DW_TAG_imported_declaration,
10158 .scope = extra.scope,
10159 .entity = extra.entity,
10160 .file = extra.file,
10161 .line = extra.line,
10162 .name = switch (extra.name) {
10163 .none => null,
10164 else => extra.name,
10165 },
10166 .elements = null,
10167 }, writer);
10168 },
1013510169 .subroutine_type => {
1013610170 const extra = self.metadataExtraData(Metadata.SubroutineType, metadata_item.data);
1013710171 try metadata_formatter.specialized(.@"!", .DISubroutineType, .{
......@@ -10255,11 +10289,7 @@ pub fn printUnbuffered(
1025510289 .file = extra.file,
1025610290 .line = extra.line,
1025710291 .type = extra.ty,
10258 .isLocal = switch (kind) {
10259 .global_var => false,
10260 .@"global_var local" => true,
10261 else => unreachable,
10262 },
10292 .isLocal = kind != .global_var,
1026310293 .isDefinition = true,
1026410294 .declaration = null,
1026510295 .templateParams = null,
......@@ -11612,7 +11642,17 @@ fn addMetadataExtraAssumeCapacity(self: *Builder, extra: anytype) Metadata.Item.
1161211642 u32 => value,
1161311643 MetadataString, Metadata, Variable.Index, Value => @intFromEnum(value),
1161411644 Metadata.DIFlags => @bitCast(value),
11615 else => @compileError("bad field type: " ++ @typeName(field.type)),
11645 else => blk: {
11646 switch (@typeInfo(field.type)) {
11647 .Struct => |s| {
11648 if (s.backing_integer == u32)
11649 break :blk @bitCast(value);
11650 @compileLog(s.layout, s.backing_integer);
11651 },
11652 else => {},
11653 }
11654 @compileError("bad field type: " ++ @typeName(field.type));
11655 },
1161611656 });
1161711657 }
1161811658 return result;
......@@ -11651,7 +11691,7 @@ fn metadataExtraDataTrail(
1165111691 u32 => value,
1165211692 MetadataString, Metadata, Variable.Index, Value => @enumFromInt(value),
1165311693 Metadata.DIFlags => @bitCast(value),
11654 else => @compileError("bad field type: " ++ @typeName(field.type)),
11694 else => @bitCast(value),
1165511695 };
1165611696 return .{
1165711697 .data = result,
......@@ -11740,15 +11780,17 @@ pub fn debugCompileUnit(
1174011780 producer: MetadataString,
1174111781 enums: Metadata,
1174211782 globals: Metadata,
11783 imports: Metadata,
1174311784 options: Metadata.CompileUnit.Options,
1174411785) Allocator.Error!Metadata {
1174511786 try self.ensureUnusedMetadataCapacity(1, Metadata.CompileUnit, 0);
11746 return self.debugCompileUnitAssumeCapacity(file, producer, enums, globals, options);
11787 return self.debugCompileUnitAssumeCapacity(file, producer, enums, globals, imports, options);
1174711788}
1174811789
1174911790pub fn debugSubprogram(
1175011791 self: *Builder,
1175111792 file: Metadata,
11793 scope: Metadata,
1175211794 name: MetadataString,
1175311795 linkage_name: MetadataString,
1175411796 line: u32,
......@@ -11760,6 +11802,7 @@ pub fn debugSubprogram(
1176011802 try self.ensureUnusedMetadataCapacity(1, Metadata.Subprogram, 0);
1176111803 return self.debugSubprogramAssumeCapacity(
1176211804 file,
11805 scope,
1176311806 name,
1176411807 linkage_name,
1176511808 line,
......@@ -11815,6 +11858,7 @@ pub fn debugStructType(
1181511858 size_in_bits: u64,
1181611859 align_in_bits: u64,
1181711860 fields_tuple: Metadata,
11861 is_byref: bool,
1181811862) Allocator.Error!Metadata {
1181911863 try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0);
1182011864 return self.debugStructTypeAssumeCapacity(
......@@ -11826,6 +11870,7 @@ pub fn debugStructType(
1182611870 size_in_bits,
1182711871 align_in_bits,
1182811872 fields_tuple,
11873 is_byref,
1182911874 );
1183011875}
1183111876
......@@ -11839,6 +11884,7 @@ pub fn debugUnionType(
1183911884 size_in_bits: u64,
1184011885 align_in_bits: u64,
1184111886 fields_tuple: Metadata,
11887 is_byref: bool,
1184211888) Allocator.Error!Metadata {
1184311889 try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0);
1184411890 return self.debugUnionTypeAssumeCapacity(
......@@ -11850,6 +11896,7 @@ pub fn debugUnionType(
1185011896 size_in_bits,
1185111897 align_in_bits,
1185211898 fields_tuple,
11899 is_byref,
1185311900 );
1185411901}
1185511902
......@@ -11973,6 +12020,53 @@ pub fn debugMemberType(
1197312020 );
1197412021}
1197512022
12023pub fn debugTypedef(
12024 self: *Builder,
12025 name: MetadataString,
12026 file: Metadata,
12027 scope: Metadata,
12028 line: u32,
12029 underlying_type: Metadata,
12030 align_in_bits: u64,
12031) Allocator.Error!Metadata {
12032 try self.ensureUnusedMetadataCapacity(1, Metadata.DerivedType, 0);
12033
12034 assert(!self.strip);
12035 return self.metadataSimpleAssumeCapacity(.derived_typedef, Metadata.DerivedType{
12036 .name = name,
12037 .file = file,
12038 .scope = scope,
12039 .line = line,
12040 .underlying_type = underlying_type,
12041 .size_in_bits_lo = 0,
12042 .size_in_bits_hi = 0,
12043 .align_in_bits_lo = @truncate(align_in_bits),
12044 .align_in_bits_hi = @truncate(align_in_bits >> 32),
12045 .offset_in_bits_lo = 0,
12046 .offset_in_bits_hi = 0,
12047 });
12048}
12049
12050pub fn debugImportDeclaration(
12051 self: *Builder,
12052 name: MetadataString,
12053 file: Metadata,
12054 scope: Metadata,
12055 line: u32,
12056 entity: Metadata,
12057) Allocator.Error!Metadata {
12058 try self.ensureUnusedMetadataCapacity(1, Metadata.ImportedEntity, 0);
12059
12060 assert(!self.strip);
12061 return self.metadataSimpleAssumeCapacity(.imported_declaration, Metadata.ImportedEntity{
12062 .name = name,
12063 .file = file,
12064 .scope = scope,
12065 .line = line,
12066 .entity = entity,
12067 });
12068}
12069
1197612070pub fn debugSubroutineType(
1197712071 self: *Builder,
1197812072 types_tuple: Metadata,
......@@ -12063,7 +12157,7 @@ pub fn debugGlobalVar(
1206312157 line: u32,
1206412158 ty: Metadata,
1206512159 variable: Variable.Index,
12066 options: Metadata.GlobalVar.Options,
12160 internal: bool,
1206712161) Allocator.Error!Metadata {
1206812162 try self.ensureUnusedMetadataCapacity(1, Metadata.GlobalVar, 0);
1206912163 return self.debugGlobalVarAssumeCapacity(
......@@ -12074,7 +12168,7 @@ pub fn debugGlobalVar(
1207412168 line,
1207512169 ty,
1207612170 variable,
12077 options,
12171 internal,
1207812172 );
1207912173}
1208012174
......@@ -12207,6 +12301,7 @@ pub fn debugCompileUnitAssumeCapacity(
1220712301 producer: MetadataString,
1220812302 enums: Metadata,
1220912303 globals: Metadata,
12304 imports: Metadata,
1221012305 options: Metadata.CompileUnit.Options,
1221112306) Metadata {
1221212307 assert(!self.strip);
......@@ -12217,6 +12312,7 @@ pub fn debugCompileUnitAssumeCapacity(
1221712312 .producer = producer,
1221812313 .enums = enums,
1221912314 .globals = globals,
12315 .imports = imports,
1222012316 },
1222112317 );
1222212318}
......@@ -12224,6 +12320,7 @@ pub fn debugCompileUnitAssumeCapacity(
1222412320fn debugSubprogramAssumeCapacity(
1222512321 self: *Builder,
1222612322 file: Metadata,
12323 scope: Metadata,
1222712324 name: MetadataString,
1222812325 linkage_name: MetadataString,
1222912326 line: u32,
......@@ -12237,6 +12334,7 @@ fn debugSubprogramAssumeCapacity(
1223712334 @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2)));
1223812335 return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{
1223912336 .file = file,
12337 .scope = scope,
1224012338 .name = name,
1224112339 .linkage_name = linkage_name,
1224212340 .line = line,
......@@ -12320,6 +12418,7 @@ fn debugStructTypeAssumeCapacity(
1232012418 size_in_bits: u64,
1232112419 align_in_bits: u64,
1232212420 fields_tuple: Metadata,
12421 is_byref: bool,
1232312422) Metadata {
1232412423 assert(!self.strip);
1232512424 return self.debugCompositeTypeAssumeCapacity(
......@@ -12332,6 +12431,7 @@ fn debugStructTypeAssumeCapacity(
1233212431 size_in_bits,
1233312432 align_in_bits,
1233412433 fields_tuple,
12434 is_byref,
1233512435 );
1233612436}
1233712437
......@@ -12345,6 +12445,7 @@ fn debugUnionTypeAssumeCapacity(
1234512445 size_in_bits: u64,
1234612446 align_in_bits: u64,
1234712447 fields_tuple: Metadata,
12448 is_byref: bool,
1234812449) Metadata {
1234912450 assert(!self.strip);
1235012451 return self.debugCompositeTypeAssumeCapacity(
......@@ -12357,6 +12458,7 @@ fn debugUnionTypeAssumeCapacity(
1235712458 size_in_bits,
1235812459 align_in_bits,
1235912460 fields_tuple,
12461 is_byref,
1236012462 );
1236112463}
1236212464
......@@ -12382,6 +12484,7 @@ fn debugEnumerationTypeAssumeCapacity(
1238212484 size_in_bits,
1238312485 align_in_bits,
1238412486 fields_tuple,
12487 false, // is_byref
1238512488 );
1238612489}
1238712490
......@@ -12407,6 +12510,7 @@ fn debugArrayTypeAssumeCapacity(
1240712510 size_in_bits,
1240812511 align_in_bits,
1240912512 fields_tuple,
12513 size_in_bits > 0, // is_byref
1241012514 );
1241112515}
1241212516
......@@ -12432,6 +12536,7 @@ fn debugVectorTypeAssumeCapacity(
1243212536 size_in_bits,
1243312537 align_in_bits,
1243412538 fields_tuple,
12539 false,
1243512540 );
1243612541}
1243712542
......@@ -12446,6 +12551,7 @@ fn debugCompositeTypeAssumeCapacity(
1244612551 size_in_bits: u64,
1244712552 align_in_bits: u64,
1244812553 fields_tuple: Metadata,
12554 is_byref: bool,
1244912555) Metadata {
1245012556 assert(!self.strip);
1245112557 return self.metadataSimpleAssumeCapacity(tag, Metadata.CompositeType{
......@@ -12459,6 +12565,7 @@ fn debugCompositeTypeAssumeCapacity(
1245912565 .align_in_bits_lo = @truncate(align_in_bits),
1246012566 .align_in_bits_hi = @truncate(align_in_bits >> 32),
1246112567 .fields_tuple = fields_tuple,
12568 .flags = .{ .is_byref = is_byref },
1246212569 });
1246312570}
1246412571
......@@ -12769,11 +12876,11 @@ fn debugGlobalVarAssumeCapacity(
1276912876 line: u32,
1277012877 ty: Metadata,
1277112878 variable: Variable.Index,
12772 options: Metadata.GlobalVar.Options,
12879 internal: bool,
1277312880) Metadata {
1277412881 assert(!self.strip);
1277512882 return self.metadataDistinctAssumeCapacity(
12776 if (options.local) .@"global_var local" else .global_var,
12883 if (internal) .@"global_var local" else .global_var,
1277712884 Metadata.GlobalVar{
1277812885 .name = name,
1277912886 .linkage_name = linkage_name,
......@@ -13804,6 +13911,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1380413911 },
1380513912 .enums = extra.enums,
1380613913 .globals = extra.globals,
13914 .imports = extra.imports,
1380713915 }, metadata_adapter);
1380813916 },
1380913917 .subprogram,
......@@ -13818,7 +13926,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1381813926 const extra = self.metadataExtraData(Metadata.Subprogram, data);
1381913927
1382013928 try metadata_block.writeAbbrevAdapted(MetadataBlock.Subprogram{
13821 .scope = extra.file,
13929 .scope = extra.scope,
1382213930 .name = extra.name,
1382313931 .linkage_name = extra.linkage_name,
1382413932 .file = extra.file,
......@@ -13892,18 +14000,24 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1389214000 .underlying_type = extra.underlying_type,
1389314001 .size_in_bits = extra.bitSize(),
1389414002 .align_in_bits = extra.bitAlign(),
13895 .flags = if (kind == .composite_vector_type) .{ .Vector = true } else .{},
14003 .flags = .{
14004 .Vector = kind == .composite_vector_type,
14005 .EnumClass = kind == .composite_enumeration_type,
14006 .TypePassbyReference = extra.flags.is_byref,
14007 },
1389614008 .elements = extra.fields_tuple,
1389714009 }, metadata_adapter);
1389814010 },
1389914011 .derived_pointer_type,
1390014012 .derived_member_type,
14013 .derived_typedef,
1390114014 => |kind| {
1390214015 const extra = self.metadataExtraData(Metadata.DerivedType, data);
1390314016 try metadata_block.writeAbbrevAdapted(MetadataBlock.DerivedType{
1390414017 .tag = switch (kind) {
1390514018 .derived_pointer_type => DW.TAG.pointer_type,
1390614019 .derived_member_type => DW.TAG.member,
14020 .derived_typedef => DW.TAG.typedef,
1390714021 else => unreachable,
1390814022 },
1390914023 .name = extra.name,
......@@ -13914,6 +14028,20 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1391414028 .size_in_bits = extra.bitSize(),
1391514029 .align_in_bits = extra.bitAlign(),
1391614030 .offset_in_bits = extra.bitOffset(),
14031 .flags = .{
14032 .StaticMember = false,
14033 },
14034 }, metadata_adapter);
14035 },
14036 .imported_declaration => {
14037 const extra = self.metadataExtraData(Metadata.ImportedEntity, data);
14038 try metadata_block.writeAbbrevAdapted(MetadataBlock.ImportedEntity{
14039 .tag = DW.TAG.imported_declaration,
14040 .scope = extra.scope,
14041 .entity = extra.entity,
14042 .line = extra.line,
14043 .name = extra.name,
14044 .file = extra.file,
1391714045 }, metadata_adapter);
1391814046 },
1391914047 .subroutine_type => {
src/codegen/llvm/ir.zig+27-3
......@@ -649,6 +649,7 @@ pub const MetadataBlock = struct {
649649 BasicType,
650650 CompositeType,
651651 DerivedType,
652 ImportedEntity,
652653 SubroutineType,
653654 Enumerator,
654655 Subrange,
......@@ -694,7 +695,7 @@ pub const MetadataBlock = struct {
694695 pub const ops = [_]AbbrevOp{
695696 .{ .literal = 20 },
696697 .{ .literal = 1 }, // is distinct
697 .{ .literal = std.dwarf.LANG.C99 }, // source language
698 .{ .literal = std.dwarf.LANG.C_plus_plus_11 }, // source language
698699 MetadataAbbrev, // file
699700 MetadataAbbrev, // producer
700701 .{ .fixed = 1 }, // isOptimized
......@@ -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 {
......@@ -863,7 +865,7 @@ pub const MetadataBlock = struct {
863865 .{ .vbr = 6 }, // size in bits
864866 .{ .vbr = 6 }, // align in bits
865867 .{ .vbr = 6 }, // offset in bits
866 .{ .literal = 0 }, // flags
868 .{ .fixed = 32 }, // flags
867869 .{ .literal = 0 }, // extra data
868870 };
869871
......@@ -876,6 +878,28 @@ pub const MetadataBlock = struct {
876878 size_in_bits: u64,
877879 align_in_bits: u64,
878880 offset_in_bits: u64,
881 flags: Builder.Metadata.DIFlags,
882 };
883
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,
879903 };
880904
881905 pub const SubroutineType = struct {
test/cases/llvm/debug_types.zig created+23
......@@ -0,0 +1,23 @@
1const Ty = struct {
2 pub const A = void;
3 pub const B = @Vector(2, u0);
4 pub const C = u0;
5 pub const D = enum (u0) {};
6 pub const E = type;
7 pub const F = 1;
8 pub const G = 1.0;
9 pub const H = undefined;
10 pub const I = null;
11 pub const J = .foo;
12};
13pub fn main() void {
14 inline for (@typeInfo(Ty).Struct.decls) |d|{
15 _ = @field(Ty, d.name);
16 }
17}
18
19// compile
20// output_mode=Exe
21// backend=llvm
22// target=x86_64-linux,x86_64-macos
23//
\ No newline at end of file