| ... | @@ -806,17 +806,14 @@ pub const Object = struct { | ... | @@ -806,17 +806,14 @@ pub const Object = struct { |
| 806 | | 806 | |
| 807 | debug_enums_fwd_ref: Builder.Metadata, | 807 | debug_enums_fwd_ref: Builder.Metadata, |
| 808 | debug_globals_fwd_ref: Builder.Metadata, | 808 | debug_globals_fwd_ref: Builder.Metadata, |
| 809 | debug_imports_fwd_ref: Builder.Metadata, | | |
| 810 | | 809 | |
| 811 | debug_enums: std.ArrayListUnmanaged(Builder.Metadata), | 810 | debug_enums: std.ArrayListUnmanaged(Builder.Metadata), |
| 812 | debug_globals: std.ArrayListUnmanaged(Builder.Metadata), | 811 | debug_globals: std.ArrayListUnmanaged(Builder.Metadata), |
| 813 | debug_imports: std.ArrayListUnmanaged(Builder.Metadata), | | |
| 814 | | 812 | |
| 815 | debug_file_map: std.AutoHashMapUnmanaged(*const Zcu.File, Builder.Metadata), | 813 | debug_file_map: std.AutoHashMapUnmanaged(*const Zcu.File, Builder.Metadata), |
| 816 | debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata), | 814 | debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata), |
| 817 | | 815 | |
| 818 | // The value says whether this namespace's type is runtime-required. | 816 | debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata), |
| 819 | debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(Type, bool), | | |
| 820 | | 817 | |
| 821 | target: std.Target, | 818 | target: std.Target, |
| 822 | /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function, | 819 | /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function, |
| ... | @@ -881,7 +878,7 @@ pub const Object = struct { | ... | @@ -881,7 +878,7 @@ pub const Object = struct { |
| 881 | | 878 | |
| 882 | builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }}); | 879 | builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }}); |
| 883 | | 880 | |
| 884 | const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref, const debug_imports_fwd_ref = | 881 | const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref = |
| 885 | if (!builder.strip) | 882 | if (!builder.strip) |
| 886 | debug_info: { | 883 | debug_info: { |
| 887 | // We fully resolve all paths at this point to avoid lack of | 884 | // We fully resolve all paths at this point to avoid lack of |
| ... | @@ -913,7 +910,6 @@ pub const Object = struct { | ... | @@ -913,7 +910,6 @@ pub const Object = struct { |
| 913 | | 910 | |
| 914 | const debug_enums_fwd_ref = try builder.debugForwardReference(); | 911 | const debug_enums_fwd_ref = try builder.debugForwardReference(); |
| 915 | const debug_globals_fwd_ref = try builder.debugForwardReference(); | 912 | const debug_globals_fwd_ref = try builder.debugForwardReference(); |
| 916 | const debug_imports_fwd_ref = try builder.debugForwardReference(); | | |
| 917 | | 913 | |
| 918 | const debug_compile_unit = try builder.debugCompileUnit( | 914 | const debug_compile_unit = try builder.debugCompileUnit( |
| 919 | debug_file, | 915 | debug_file, |
| ... | @@ -926,7 +922,6 @@ pub const Object = struct { | ... | @@ -926,7 +922,6 @@ pub const Object = struct { |
| 926 | }), | 922 | }), |
| 927 | debug_enums_fwd_ref, | 923 | debug_enums_fwd_ref, |
| 928 | debug_globals_fwd_ref, | 924 | debug_globals_fwd_ref, |
| 929 | debug_imports_fwd_ref, | | |
| 930 | .{ .optimized = comp.root_mod.optimize_mode != .Debug }, | 925 | .{ .optimized = comp.root_mod.optimize_mode != .Debug }, |
| 931 | ); | 926 | ); |
| 932 | | 927 | |
| ... | @@ -982,8 +977,8 @@ pub const Object = struct { | ... | @@ -982,8 +977,8 @@ pub const Object = struct { |
| 982 | } | 977 | } |
| 983 | | 978 | |
| 984 | try builder.debugNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit}); | 979 | try builder.debugNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit}); |
| 985 | break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref, debug_imports_fwd_ref }; | 980 | break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref }; |
| 986 | } else .{.none} ** 4; | 981 | } else .{.none} ** 3; |
| 987 | | 982 | |
| 988 | const obj = try arena.create(Object); | 983 | const obj = try arena.create(Object); |
| 989 | obj.* = .{ | 984 | obj.* = .{ |
| ... | @@ -996,10 +991,8 @@ pub const Object = struct { | ... | @@ -996,10 +991,8 @@ pub const Object = struct { |
| 996 | .debug_compile_unit = debug_compile_unit, | 991 | .debug_compile_unit = debug_compile_unit, |
| 997 | .debug_enums_fwd_ref = debug_enums_fwd_ref, | 992 | .debug_enums_fwd_ref = debug_enums_fwd_ref, |
| 998 | .debug_globals_fwd_ref = debug_globals_fwd_ref, | 993 | .debug_globals_fwd_ref = debug_globals_fwd_ref, |
| 999 | .debug_imports_fwd_ref = debug_imports_fwd_ref, | | |
| 1000 | .debug_enums = .{}, | 994 | .debug_enums = .{}, |
| 1001 | .debug_globals = .{}, | 995 | .debug_globals = .{}, |
| 1002 | .debug_imports = .{}, | | |
| 1003 | .debug_file_map = .{}, | 996 | .debug_file_map = .{}, |
| 1004 | .debug_type_map = .{}, | 997 | .debug_type_map = .{}, |
| 1005 | .debug_unresolved_namespace_scopes = .{}, | 998 | .debug_unresolved_namespace_scopes = .{}, |
| ... | @@ -1141,7 +1134,18 @@ pub const Object = struct { | ... | @@ -1141,7 +1134,18 @@ pub const Object = struct { |
| 1141 | try self.genModuleLevelAssembly(); | 1134 | try self.genModuleLevelAssembly(); |
| 1142 | | 1135 | |
| 1143 | if (!self.builder.strip) { | 1136 | if (!self.builder.strip) { |
| 1144 | try self.genNamespaces(); | 1137 | { |
| | 1138 | var i: usize = 0; |
| | 1139 | while (i < self.debug_unresolved_namespace_scopes.count()) : (i += 1) { |
| | 1140 | const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i]; |
| | 1141 | const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i]; |
| | 1142 | |
| | 1143 | const namespace = zcu.namespacePtr(namespace_index); |
| | 1144 | const debug_type = try self.lowerDebugType(namespace.getType(zcu)); |
| | 1145 | |
| | 1146 | self.builder.debugForwardReferenceSetType(fwd_ref, debug_type); |
| | 1147 | } |
| | 1148 | } |
| 1145 | | 1149 | |
| 1146 | self.builder.debugForwardReferenceSetType( | 1150 | self.builder.debugForwardReferenceSetType( |
| 1147 | self.debug_enums_fwd_ref, | 1151 | self.debug_enums_fwd_ref, |
| ... | @@ -1152,11 +1156,6 @@ pub const Object = struct { | ... | @@ -1152,11 +1156,6 @@ pub const Object = struct { |
| 1152 | self.debug_globals_fwd_ref, | 1156 | self.debug_globals_fwd_ref, |
| 1153 | try self.builder.debugTuple(self.debug_globals.items), | 1157 | try self.builder.debugTuple(self.debug_globals.items), |
| 1154 | ); | 1158 | ); |
| 1155 | | | |
| 1156 | self.builder.debugForwardReferenceSetType( | | |
| 1157 | self.debug_imports_fwd_ref, | | |
| 1158 | try self.builder.debugTuple(self.debug_imports.items), | | |
| 1159 | ); | | |
| 1160 | } | 1159 | } |
| 1161 | } | 1160 | } |
| 1162 | | 1161 | |
| ... | @@ -1636,19 +1635,15 @@ pub const Object = struct { | ... | @@ -1636,19 +1635,15 @@ pub const Object = struct { |
| 1636 | | 1635 | |
| 1637 | const file, const subprogram = if (!wip.strip) debug_info: { | 1636 | const file, const subprogram = if (!wip.strip) debug_info: { |
| 1638 | const file = try o.getDebugFile(file_scope); | 1637 | const file = try o.getDebugFile(file_scope); |
| 1639 | const scope = try o.lowerDebugType(zcu.declPtr(namespace.decl_index).val.toType(), false); | | |
| 1640 | | 1638 | |
| 1641 | const line_number = decl.navSrcLine(zcu) + 1; | 1639 | const line_number = decl.navSrcLine(zcu) + 1; |
| 1642 | const is_internal_linkage = decl.val.getExternFunc(zcu) == null; | 1640 | const is_internal_linkage = decl.val.getExternFunc(zcu) == null; |
| 1643 | const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu), true); | 1641 | const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu)); |
| 1644 | const decl_name = try o.builder.metadataString(decl.name.toSlice(ip)); | | |
| 1645 | const link_name = try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)); | | |
| 1646 | | 1642 | |
| 1647 | const subprogram = try o.builder.debugSubprogram( | 1643 | const subprogram = try o.builder.debugSubprogram( |
| 1648 | file, | 1644 | file, |
| 1649 | scope, | 1645 | try o.builder.metadataString(decl.name.toSlice(ip)), |
| 1650 | decl_name, | 1646 | try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)), |
| 1651 | link_name, | | |
| 1652 | line_number, | 1647 | line_number, |
| 1653 | line_number + func.lbrace_line, | 1648 | line_number + func.lbrace_line, |
| 1654 | debug_decl_type, | 1649 | debug_decl_type, |
| ... | @@ -1665,7 +1660,6 @@ pub const Object = struct { | ... | @@ -1665,7 +1660,6 @@ pub const Object = struct { |
| 1665 | }, | 1660 | }, |
| 1666 | o.debug_compile_unit, | 1661 | o.debug_compile_unit, |
| 1667 | ); | 1662 | ); |
| 1668 | | | |
| 1669 | function_index.setSubprogram(subprogram, &o.builder); | 1663 | function_index.setSubprogram(subprogram, &o.builder); |
| 1670 | break :debug_info .{ file, subprogram }; | 1664 | break :debug_info .{ file, subprogram }; |
| 1671 | } else .{.none} ** 2; | 1665 | } else .{.none} ** 2; |
| ... | @@ -1913,7 +1907,6 @@ pub const Object = struct { | ... | @@ -1913,7 +1907,6 @@ pub const Object = struct { |
| 1913 | pub fn lowerDebugType( | 1907 | pub fn lowerDebugType( |
| 1914 | o: *Object, | 1908 | o: *Object, |
| 1915 | ty: Type, | 1909 | ty: Type, |
| 1916 | required_by_runtime: bool, | | |
| 1917 | ) Allocator.Error!Builder.Metadata { | 1910 | ) Allocator.Error!Builder.Metadata { |
| 1918 | assert(!o.builder.strip); | 1911 | assert(!o.builder.strip); |
| 1919 | | 1912 | |
| ... | @@ -1923,13 +1916,7 @@ pub const Object = struct { | ... | @@ -1923,13 +1916,7 @@ pub const Object = struct { |
| 1923 | const zcu = pt.zcu; | 1916 | const zcu = pt.zcu; |
| 1924 | const ip = &zcu.intern_pool; | 1917 | const ip = &zcu.intern_pool; |
| 1925 | | 1918 | |
| 1926 | if (o.debug_type_map.get(ty)) |debug_type| { | 1919 | if (o.debug_type_map.get(ty)) |debug_type| return debug_type; |
| 1927 | if (required_by_runtime) { | | |
| 1928 | if (o.debug_unresolved_namespace_scopes.getEntry(ty)) |entry| | | |
| 1929 | entry.value_ptr.* = true; | | |
| 1930 | } | | |
| 1931 | return debug_type; | | |
| 1932 | } | | |
| 1933 | | 1920 | |
| 1934 | switch (ty.zigTypeTag(zcu)) { | 1921 | switch (ty.zigTypeTag(zcu)) { |
| 1935 | .Void, | 1922 | .Void, |
| ... | @@ -1944,9 +1931,10 @@ pub const Object = struct { | ... | @@ -1944,9 +1931,10 @@ pub const Object = struct { |
| 1944 | }, | 1931 | }, |
| 1945 | .Int => { | 1932 | .Int => { |
| 1946 | const info = ty.intInfo(zcu); | 1933 | const info = ty.intInfo(zcu); |
| 1947 | const int_name = try o.allocTypeName(ty); | 1934 | assert(info.bits != 0); |
| 1948 | defer gpa.free(int_name); | 1935 | const name = try o.allocTypeName(ty); |
| 1949 | const builder_name = try o.builder.metadataString(int_name); | 1936 | defer gpa.free(name); |
| | 1937 | const builder_name = try o.builder.metadataString(name); |
| 1950 | const debug_bits = ty.abiSize(pt) * 8; // lldb cannot handle non-byte sized types | 1938 | const debug_bits = ty.abiSize(pt) * 8; // lldb cannot handle non-byte sized types |
| 1951 | const debug_int_type = switch (info.signedness) { | 1939 | const debug_int_type = switch (info.signedness) { |
| 1952 | .signed => try o.builder.debugSignedType(builder_name, debug_bits), | 1940 | .signed => try o.builder.debugSignedType(builder_name, debug_bits), |
| ... | @@ -1955,12 +1943,68 @@ pub const Object = struct { | ... | @@ -1955,12 +1943,68 @@ pub const Object = struct { |
| 1955 | try o.debug_type_map.put(gpa, ty, debug_int_type); | 1943 | try o.debug_type_map.put(gpa, ty, debug_int_type); |
| 1956 | return debug_int_type; | 1944 | return debug_int_type; |
| 1957 | }, | 1945 | }, |
| | 1946 | .Enum => { |
| | 1947 | const owner_decl_index = ty.getOwnerDecl(zcu); |
| | 1948 | const owner_decl = zcu.declPtr(owner_decl_index); |
| | 1949 | |
| | 1950 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| | 1951 | const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); |
| | 1952 | try o.debug_type_map.put(gpa, ty, debug_enum_type); |
| | 1953 | return debug_enum_type; |
| | 1954 | } |
| | 1955 | |
| | 1956 | const enum_type = ip.loadEnumType(ty.toIntern()); |
| | 1957 | |
| | 1958 | const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len); |
| | 1959 | defer gpa.free(enumerators); |
| | 1960 | |
| | 1961 | const int_ty = Type.fromInterned(enum_type.tag_ty); |
| | 1962 | const int_info = ty.intInfo(zcu); |
| | 1963 | assert(int_info.bits != 0); |
| | 1964 | |
| | 1965 | for (enum_type.names.get(ip), 0..) |field_name_ip, i| { |
| | 1966 | var bigint_space: Value.BigIntSpace = undefined; |
| | 1967 | const bigint = if (enum_type.values.len != 0) |
| | 1968 | Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt) |
| | 1969 | else |
| | 1970 | std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst(); |
| | 1971 | |
| | 1972 | enumerators[i] = try o.builder.debugEnumerator( |
| | 1973 | try o.builder.metadataString(field_name_ip.toSlice(ip)), |
| | 1974 | int_info.signedness == .unsigned, |
| | 1975 | int_info.bits, |
| | 1976 | bigint, |
| | 1977 | ); |
| | 1978 | } |
| | 1979 | |
| | 1980 | const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu); |
| | 1981 | const file = try o.getDebugFile(file_scope); |
| | 1982 | const scope = try o.namespaceToDebugScope(owner_decl.src_namespace); |
| | 1983 | |
| | 1984 | const name = try o.allocTypeName(ty); |
| | 1985 | defer gpa.free(name); |
| | 1986 | |
| | 1987 | const debug_enum_type = try o.builder.debugEnumerationType( |
| | 1988 | try o.builder.metadataString(name), |
| | 1989 | file, |
| | 1990 | scope, |
| | 1991 | owner_decl.typeSrcLine(zcu) + 1, // Line |
| | 1992 | try o.lowerDebugType(int_ty), |
| | 1993 | ty.abiSize(pt) * 8, |
| | 1994 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| | 1995 | try o.builder.debugTuple(enumerators), |
| | 1996 | ); |
| | 1997 | |
| | 1998 | try o.debug_type_map.put(gpa, ty, debug_enum_type); |
| | 1999 | try o.debug_enums.append(gpa, debug_enum_type); |
| | 2000 | return debug_enum_type; |
| | 2001 | }, |
| 1958 | .Float => { | 2002 | .Float => { |
| 1959 | const bits = ty.floatBits(target); | 2003 | const bits = ty.floatBits(target); |
| 1960 | const float_name = try o.allocTypeName(ty); | 2004 | const name = try o.allocTypeName(ty); |
| 1961 | defer gpa.free(float_name); | 2005 | defer gpa.free(name); |
| 1962 | const debug_float_type = try o.builder.debugFloatType( | 2006 | const debug_float_type = try o.builder.debugFloatType( |
| 1963 | try o.builder.metadataString(float_name), | 2007 | try o.builder.metadataString(name), |
| 1964 | bits, | 2008 | bits, |
| 1965 | ); | 2009 | ); |
| 1966 | try o.debug_type_map.put(gpa, ty, debug_float_type); | 2010 | try o.debug_type_map.put(gpa, ty, debug_float_type); |
| ... | @@ -2002,7 +2046,7 @@ pub const Object = struct { | ... | @@ -2002,7 +2046,7 @@ pub const Object = struct { |
| 2002 | }, | 2046 | }, |
| 2003 | }, | 2047 | }, |
| 2004 | }); | 2048 | }); |
| 2005 | const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty, required_by_runtime); | 2049 | const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty); |
| 2006 | try o.debug_type_map.put(gpa, ty, debug_ptr_type); | 2050 | try o.debug_type_map.put(gpa, ty, debug_ptr_type); |
| 2007 | return debug_ptr_type; | 2051 | return debug_ptr_type; |
| 2008 | } | 2052 | } |
| ... | @@ -2018,7 +2062,6 @@ pub const Object = struct { | ... | @@ -2018,7 +2062,6 @@ pub const Object = struct { |
| 2018 | | 2062 | |
| 2019 | const name = try o.allocTypeName(ty); | 2063 | const name = try o.allocTypeName(ty); |
| 2020 | defer gpa.free(name); | 2064 | defer gpa.free(name); |
| 2021 | | | |
| 2022 | const line = 0; | 2065 | const line = 0; |
| 2023 | | 2066 | |
| 2024 | const ptr_size = ptr_ty.abiSize(pt); | 2067 | const ptr_size = ptr_ty.abiSize(pt); |
| ... | @@ -2033,7 +2076,7 @@ pub const Object = struct { | ... | @@ -2033,7 +2076,7 @@ pub const Object = struct { |
| 2033 | .none, // File | 2076 | .none, // File |
| 2034 | debug_fwd_ref, | 2077 | debug_fwd_ref, |
| 2035 | 0, // Line | 2078 | 0, // Line |
| 2036 | try o.lowerDebugType(ptr_ty, required_by_runtime), | 2079 | try o.lowerDebugType(ptr_ty), |
| 2037 | ptr_size * 8, | 2080 | ptr_size * 8, |
| 2038 | (ptr_align.toByteUnits() orelse 0) * 8, | 2081 | (ptr_align.toByteUnits() orelse 0) * 8, |
| 2039 | 0, // Offset | 2082 | 0, // Offset |
| ... | @@ -2044,7 +2087,7 @@ pub const Object = struct { | ... | @@ -2044,7 +2087,7 @@ pub const Object = struct { |
| 2044 | .none, // File | 2087 | .none, // File |
| 2045 | debug_fwd_ref, | 2088 | debug_fwd_ref, |
| 2046 | 0, // Line | 2089 | 0, // Line |
| 2047 | try o.lowerDebugType(len_ty, required_by_runtime), | 2090 | try o.lowerDebugType(len_ty), |
| 2048 | len_size * 8, | 2091 | len_size * 8, |
| 2049 | (len_align.toByteUnits() orelse 0) * 8, | 2092 | (len_align.toByteUnits() orelse 0) * 8, |
| 2050 | len_offset * 8, | 2093 | len_offset * 8, |
| ... | @@ -2062,7 +2105,6 @@ pub const Object = struct { | ... | @@ -2062,7 +2105,6 @@ pub const Object = struct { |
| 2062 | debug_ptr_type, | 2105 | debug_ptr_type, |
| 2063 | debug_len_type, | 2106 | debug_len_type, |
| 2064 | }), | 2107 | }), |
| 2065 | isByRef(ty, pt), | | |
| 2066 | ); | 2108 | ); |
| 2067 | | 2109 | |
| 2068 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_slice_type); | 2110 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_slice_type); |
| ... | @@ -2074,7 +2116,7 @@ pub const Object = struct { | ... | @@ -2074,7 +2116,7 @@ pub const Object = struct { |
| 2074 | return debug_slice_type; | 2116 | return debug_slice_type; |
| 2075 | } | 2117 | } |
| 2076 | | 2118 | |
| 2077 | const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child), required_by_runtime); | 2119 | const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child)); |
| 2078 | | 2120 | |
| 2079 | const name = try o.allocTypeName(ty); | 2121 | const name = try o.allocTypeName(ty); |
| 2080 | defer gpa.free(name); | 2122 | defer gpa.free(name); |
| ... | @@ -2098,13 +2140,41 @@ pub const Object = struct { | ... | @@ -2098,13 +2140,41 @@ pub const Object = struct { |
| 2098 | | 2140 | |
| 2099 | return debug_ptr_type; | 2141 | return debug_ptr_type; |
| 2100 | }, | 2142 | }, |
| | 2143 | .Opaque => { |
| | 2144 | if (ty.toIntern() == .anyopaque_type) { |
| | 2145 | const debug_opaque_type = try o.builder.debugSignedType( |
| | 2146 | try o.builder.metadataString("anyopaque"), |
| | 2147 | 0, |
| | 2148 | ); |
| | 2149 | try o.debug_type_map.put(gpa, ty, debug_opaque_type); |
| | 2150 | return debug_opaque_type; |
| | 2151 | } |
| | 2152 | |
| | 2153 | const name = try o.allocTypeName(ty); |
| | 2154 | defer gpa.free(name); |
| | 2155 | const owner_decl_index = ty.getOwnerDecl(zcu); |
| | 2156 | const owner_decl = zcu.declPtr(owner_decl_index); |
| | 2157 | const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu); |
| | 2158 | const debug_opaque_type = try o.builder.debugStructType( |
| | 2159 | try o.builder.metadataString(name), |
| | 2160 | try o.getDebugFile(file_scope), |
| | 2161 | try o.namespaceToDebugScope(owner_decl.src_namespace), |
| | 2162 | owner_decl.typeSrcLine(zcu) + 1, // Line |
| | 2163 | .none, // Underlying type |
| | 2164 | 0, // Size |
| | 2165 | 0, // Align |
| | 2166 | .none, // Fields |
| | 2167 | ); |
| | 2168 | try o.debug_type_map.put(gpa, ty, debug_opaque_type); |
| | 2169 | return debug_opaque_type; |
| | 2170 | }, |
| 2101 | .Array => { | 2171 | .Array => { |
| 2102 | const debug_array_type = try o.builder.debugArrayType( | 2172 | const debug_array_type = try o.builder.debugArrayType( |
| 2103 | .none, // Name | 2173 | .none, // Name |
| 2104 | .none, // File | 2174 | .none, // File |
| 2105 | .none, // Scope | 2175 | .none, // Scope |
| 2106 | 0, // Line | 2176 | 0, // Line |
| 2107 | try o.lowerDebugType(ty.childType(zcu), required_by_runtime), | 2177 | try o.lowerDebugType(ty.childType(zcu)), |
| 2108 | ty.abiSize(pt) * 8, | 2178 | ty.abiSize(pt) * 8, |
| 2109 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | 2179 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2110 | try o.builder.debugTuple(&.{ | 2180 | try o.builder.debugTuple(&.{ |
| ... | @@ -2126,9 +2196,10 @@ pub const Object = struct { | ... | @@ -2126,9 +2196,10 @@ pub const Object = struct { |
| 2126 | const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) { | 2196 | const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) { |
| 2127 | .Int => blk: { | 2197 | .Int => blk: { |
| 2128 | const info = elem_ty.intInfo(zcu); | 2198 | const info = elem_ty.intInfo(zcu); |
| 2129 | const vec_name = try o.allocTypeName(ty); | 2199 | assert(info.bits != 0); |
| 2130 | defer gpa.free(vec_name); | 2200 | const name = try o.allocTypeName(ty); |
| 2131 | const builder_name = try o.builder.metadataString(vec_name); | 2201 | defer gpa.free(name); |
| | 2202 | const builder_name = try o.builder.metadataString(name); |
| 2132 | break :blk switch (info.signedness) { | 2203 | break :blk switch (info.signedness) { |
| 2133 | .signed => try o.builder.debugSignedType(builder_name, info.bits), | 2204 | .signed => try o.builder.debugSignedType(builder_name, info.bits), |
| 2134 | .unsigned => try o.builder.debugUnsignedType(builder_name, info.bits), | 2205 | .unsigned => try o.builder.debugUnsignedType(builder_name, info.bits), |
| ... | @@ -2138,7 +2209,7 @@ pub const Object = struct { | ... | @@ -2138,7 +2209,7 @@ pub const Object = struct { |
| 2138 | try o.builder.metadataString("bool"), | 2209 | try o.builder.metadataString("bool"), |
| 2139 | 1, | 2210 | 1, |
| 2140 | ), | 2211 | ), |
| 2141 | else => try o.lowerDebugType(ty.childType(zcu), required_by_runtime), | 2212 | else => try o.lowerDebugType(ty.childType(zcu)), |
| 2142 | }; | 2213 | }; |
| 2143 | | 2214 | |
| 2144 | const debug_vector_type = try o.builder.debugVectorType( | 2215 | const debug_vector_type = try o.builder.debugVectorType( |
| ... | @@ -2163,7 +2234,6 @@ pub const Object = struct { | ... | @@ -2163,7 +2234,6 @@ pub const Object = struct { |
| 2163 | .Optional => { | 2234 | .Optional => { |
| 2164 | const name = try o.allocTypeName(ty); | 2235 | const name = try o.allocTypeName(ty); |
| 2165 | defer gpa.free(name); | 2236 | defer gpa.free(name); |
| 2166 | | | |
| 2167 | const child_ty = ty.optionalChild(zcu); | 2237 | const child_ty = ty.optionalChild(zcu); |
| 2168 | if (!child_ty.hasRuntimeBitsIgnoreComptime(pt)) { | 2238 | if (!child_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2169 | const debug_bool_type = try o.builder.debugBoolType( | 2239 | const debug_bool_type = try o.builder.debugBoolType( |
| ... | @@ -2180,7 +2250,7 @@ pub const Object = struct { | ... | @@ -2180,7 +2250,7 @@ pub const Object = struct { |
| 2180 | try o.debug_type_map.put(gpa, ty, debug_fwd_ref); | 2250 | try o.debug_type_map.put(gpa, ty, debug_fwd_ref); |
| 2181 | | 2251 | |
| 2182 | if (ty.optionalReprIsPayload(zcu)) { | 2252 | if (ty.optionalReprIsPayload(zcu)) { |
| 2183 | const debug_optional_type = try o.lowerDebugType(child_ty, required_by_runtime); | 2253 | const debug_optional_type = try o.lowerDebugType(child_ty); |
| 2184 | | 2254 | |
| 2185 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); | 2255 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); |
| 2186 | | 2256 | |
| ... | @@ -2203,7 +2273,7 @@ pub const Object = struct { | ... | @@ -2203,7 +2273,7 @@ pub const Object = struct { |
| 2203 | .none, // File | 2273 | .none, // File |
| 2204 | debug_fwd_ref, | 2274 | debug_fwd_ref, |
| 2205 | 0, // Line | 2275 | 0, // Line |
| 2206 | try o.lowerDebugType(child_ty, required_by_runtime), | 2276 | try o.lowerDebugType(child_ty), |
| 2207 | payload_size * 8, | 2277 | payload_size * 8, |
| 2208 | (payload_align.toByteUnits() orelse 0) * 8, | 2278 | (payload_align.toByteUnits() orelse 0) * 8, |
| 2209 | 0, // Offset | 2279 | 0, // Offset |
| ... | @@ -2214,7 +2284,7 @@ pub const Object = struct { | ... | @@ -2214,7 +2284,7 @@ pub const Object = struct { |
| 2214 | .none, | 2284 | .none, |
| 2215 | debug_fwd_ref, | 2285 | debug_fwd_ref, |
| 2216 | 0, | 2286 | 0, |
| 2217 | try o.lowerDebugType(non_null_ty, required_by_runtime), | 2287 | try o.lowerDebugType(non_null_ty), |
| 2218 | non_null_size * 8, | 2288 | non_null_size * 8, |
| 2219 | (non_null_align.toByteUnits() orelse 0) * 8, | 2289 | (non_null_align.toByteUnits() orelse 0) * 8, |
| 2220 | non_null_offset * 8, | 2290 | non_null_offset * 8, |
| ... | @@ -2232,7 +2302,6 @@ pub const Object = struct { | ... | @@ -2232,7 +2302,6 @@ pub const Object = struct { |
| 2232 | debug_data_type, | 2302 | debug_data_type, |
| 2233 | debug_some_type, | 2303 | debug_some_type, |
| 2234 | }), | 2304 | }), |
| 2235 | isByRef(ty, pt), | | |
| 2236 | ); | 2305 | ); |
| 2237 | | 2306 | |
| 2238 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); | 2307 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); |
| ... | @@ -2247,7 +2316,7 @@ pub const Object = struct { | ... | @@ -2247,7 +2316,7 @@ pub const Object = struct { |
| 2247 | const payload_ty = ty.errorUnionPayload(zcu); | 2316 | const payload_ty = ty.errorUnionPayload(zcu); |
| 2248 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | 2317 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2249 | // TODO: Maybe remove? | 2318 | // TODO: Maybe remove? |
| 2250 | const debug_error_union_type = try o.lowerDebugType(Type.anyerror, required_by_runtime); | 2319 | const debug_error_union_type = try o.lowerDebugType(Type.anyerror); |
| 2251 | try o.debug_type_map.put(gpa, ty, debug_error_union_type); | 2320 | try o.debug_type_map.put(gpa, ty, debug_error_union_type); |
| 2252 | return debug_error_union_type; | 2321 | return debug_error_union_type; |
| 2253 | } | 2322 | } |
| ... | @@ -2284,7 +2353,7 @@ pub const Object = struct { | ... | @@ -2284,7 +2353,7 @@ pub const Object = struct { |
| 2284 | .none, // File | 2353 | .none, // File |
| 2285 | debug_fwd_ref, | 2354 | debug_fwd_ref, |
| 2286 | 0, // Line | 2355 | 0, // Line |
| 2287 | try o.lowerDebugType(Type.anyerror, required_by_runtime), | 2356 | try o.lowerDebugType(Type.anyerror), |
| 2288 | error_size * 8, | 2357 | error_size * 8, |
| 2289 | (error_align.toByteUnits() orelse 0) * 8, | 2358 | (error_align.toByteUnits() orelse 0) * 8, |
| 2290 | error_offset * 8, | 2359 | error_offset * 8, |
| ... | @@ -2294,7 +2363,7 @@ pub const Object = struct { | ... | @@ -2294,7 +2363,7 @@ pub const Object = struct { |
| 2294 | .none, // File | 2363 | .none, // File |
| 2295 | debug_fwd_ref, | 2364 | debug_fwd_ref, |
| 2296 | 0, // Line | 2365 | 0, // Line |
| 2297 | try o.lowerDebugType(payload_ty, required_by_runtime), | 2366 | try o.lowerDebugType(payload_ty), |
| 2298 | payload_size * 8, | 2367 | payload_size * 8, |
| 2299 | (payload_align.toByteUnits() orelse 0) * 8, | 2368 | (payload_align.toByteUnits() orelse 0) * 8, |
| 2300 | payload_offset * 8, | 2369 | payload_offset * 8, |
| ... | @@ -2309,7 +2378,6 @@ pub const Object = struct { | ... | @@ -2309,7 +2378,6 @@ pub const Object = struct { |
| 2309 | ty.abiSize(pt) * 8, | 2378 | ty.abiSize(pt) * 8, |
| 2310 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | 2379 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2311 | try o.builder.debugTuple(&fields), | 2380 | try o.builder.debugTuple(&fields), |
| 2312 | isByRef(ty, pt), | | |
| 2313 | ); | 2381 | ); |
| 2314 | | 2382 | |
| 2315 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_error_union_type); | 2383 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_error_union_type); |
| ... | @@ -2325,483 +2393,383 @@ pub const Object = struct { | ... | @@ -2325,483 +2393,383 @@ pub const Object = struct { |
| 2325 | try o.debug_type_map.put(gpa, ty, debug_error_set); | 2393 | try o.debug_type_map.put(gpa, ty, debug_error_set); |
| 2326 | return debug_error_set; | 2394 | return debug_error_set; |
| 2327 | }, | 2395 | }, |
| 2328 | .Fn => { | 2396 | .Struct => { |
| 2329 | const fn_info = zcu.typeToFunc(ty).?; | 2397 | const name = try o.allocTypeName(ty); |
| 2330 | | 2398 | defer gpa.free(name); |
| 2331 | var debug_param_types = std.ArrayList(Builder.Metadata).init(gpa); | | |
| 2332 | defer debug_param_types.deinit(); | | |
| 2333 | | | |
| 2334 | try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len); | | |
| 2335 | | | |
| 2336 | // Return type goes first. | | |
| 2337 | if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) { | | |
| 2338 | const sret = firstParamSRet(fn_info, pt, target); | | |
| 2339 | const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type); | | |
| 2340 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty, required_by_runtime)); | | |
| 2341 | | | |
| 2342 | if (sret) { | | |
| 2343 | const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type)); | | |
| 2344 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime)); | | |
| 2345 | } | | |
| 2346 | } else { | | |
| 2347 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void, required_by_runtime)); | | |
| 2348 | } | | |
| 2349 | | | |
| 2350 | if (Type.fromInterned(fn_info.return_type).isError(zcu) and | | |
| 2351 | zcu.comp.config.any_error_tracing) | | |
| 2352 | { | | |
| 2353 | const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType()); | | |
| 2354 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime)); | | |
| 2355 | } | | |
| 2356 | | | |
| 2357 | for (0..fn_info.param_types.len) |i| { | | |
| 2358 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]); | | |
| 2359 | if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | | |
| 2360 | | 2399 | |
| 2361 | if (isByRef(param_ty, pt)) { | 2400 | if (zcu.typeToPackedStruct(ty)) |struct_type| { |
| 2362 | const ptr_ty = try pt.singleMutPtrType(param_ty); | 2401 | const backing_int_ty = struct_type.backingIntTypeUnordered(ip); |
| 2363 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime)); | 2402 | if (backing_int_ty != .none) { |
| 2364 | } else { | 2403 | const info = Type.fromInterned(backing_int_ty).intInfo(zcu); |
| 2365 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty, required_by_runtime)); | 2404 | const builder_name = try o.builder.metadataString(name); |
| | 2405 | const debug_int_type = switch (info.signedness) { |
| | 2406 | .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8), |
| | 2407 | .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8), |
| | 2408 | }; |
| | 2409 | try o.debug_type_map.put(gpa, ty, debug_int_type); |
| | 2410 | return debug_int_type; |
| 2366 | } | 2411 | } |
| 2367 | } | 2412 | } |
| 2368 | | 2413 | |
| 2369 | const debug_function_type = try o.builder.debugSubroutineType( | 2414 | switch (ip.indexToKey(ty.toIntern())) { |
| 2370 | try o.builder.debugTuple(debug_param_types.items), | 2415 | .anon_struct_type => |tuple| { |
| 2371 | ); | 2416 | var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; |
| | 2417 | defer fields.deinit(gpa); |
| | 2418 | |
| | 2419 | try fields.ensureUnusedCapacity(gpa, tuple.types.len); |
| | 2420 | |
| | 2421 | comptime assert(struct_layout_version == 2); |
| | 2422 | var offset: u64 = 0; |
| | 2423 | |
| | 2424 | const debug_fwd_ref = try o.builder.debugForwardReference(); |
| | 2425 | |
| | 2426 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { |
| | 2427 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| | 2428 | |
| | 2429 | const field_size = Type.fromInterned(field_ty).abiSize(pt); |
| | 2430 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); |
| | 2431 | const field_offset = field_align.forward(offset); |
| | 2432 | offset = field_offset + field_size; |
| | 2433 | |
| | 2434 | const field_name = if (tuple.names.len != 0) |
| | 2435 | tuple.names.get(ip)[i].toSlice(ip) |
| | 2436 | else |
| | 2437 | try std.fmt.allocPrintZ(gpa, "{d}", .{i}); |
| | 2438 | defer if (tuple.names.len == 0) gpa.free(field_name); |
| | 2439 | |
| | 2440 | fields.appendAssumeCapacity(try o.builder.debugMemberType( |
| | 2441 | try o.builder.metadataString(field_name), |
| | 2442 | .none, // File |
| | 2443 | debug_fwd_ref, |
| | 2444 | 0, |
| | 2445 | try o.lowerDebugType(Type.fromInterned(field_ty)), |
| | 2446 | field_size * 8, |
| | 2447 | (field_align.toByteUnits() orelse 0) * 8, |
| | 2448 | field_offset * 8, |
| | 2449 | )); |
| | 2450 | } |
| 2372 | | 2451 | |
| 2373 | try o.debug_type_map.put(gpa, ty, debug_function_type); | 2452 | const debug_struct_type = try o.builder.debugStructType( |
| 2374 | return debug_function_type; | 2453 | try o.builder.metadataString(name), |
| 2375 | }, | 2454 | .none, // File |
| 2376 | .ComptimeInt => unreachable, | 2455 | o.debug_compile_unit, // Scope |
| 2377 | .ComptimeFloat => unreachable, | 2456 | 0, // Line |
| 2378 | .Type => unreachable, | 2457 | .none, // Underlying type |
| 2379 | .Undefined => unreachable, | 2458 | ty.abiSize(pt) * 8, |
| 2380 | .Null => unreachable, | 2459 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2381 | .EnumLiteral => unreachable, | 2460 | try o.builder.debugTuple(fields.items), |
| | 2461 | ); |
| 2382 | | 2462 | |
| 2383 | .Frame => @panic("TODO implement lowerDebugType for Frame types"), | 2463 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type); |
| 2384 | .AnyFrame => @panic("TODO implement lowerDebugType for AnyFrame types"), | | |
| 2385 | // These are the types that need a correct scope. | | |
| 2386 | .Enum, .Struct, .Union, .Opaque => {}, | | |
| 2387 | } | | |
| 2388 | const fwd_ref = try o.builder.debugForwardReference(); | | |
| 2389 | try o.debug_type_map.put(gpa, ty, fwd_ref); | | |
| 2390 | try o.debug_unresolved_namespace_scopes.put(gpa, ty, required_by_runtime); | | |
| 2391 | | 2464 | |
| 2392 | return fwd_ref; | 2465 | try o.debug_type_map.put(gpa, ty, debug_struct_type); |
| 2393 | } | 2466 | return debug_struct_type; |
| | 2467 | }, |
| | 2468 | .struct_type => { |
| | 2469 | if (!ip.loadStructType(ty.toIntern()).haveFieldTypes(ip)) { |
| | 2470 | // This can happen if a struct type makes it all the way to |
| | 2471 | // flush() without ever being instantiated or referenced (even |
| | 2472 | // via pointer). The only reason we are hearing about it now is |
| | 2473 | // that it is being used as a namespace to put other debug types |
| | 2474 | // into. Therefore we can satisfy this by making an empty namespace, |
| | 2475 | // rather than changing the frontend to unnecessarily resolve the |
| | 2476 | // struct field types. |
| | 2477 | const owner_decl_index = ty.getOwnerDecl(zcu); |
| | 2478 | const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); |
| | 2479 | try o.debug_type_map.put(gpa, ty, debug_struct_type); |
| | 2480 | return debug_struct_type; |
| | 2481 | } |
| | 2482 | }, |
| | 2483 | else => {}, |
| | 2484 | } |
| 2394 | | 2485 | |
| 2395 | fn genNamespaces(o: *Object) !void { | 2486 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2396 | const gpa = o.gpa; | 2487 | const owner_decl_index = ty.getOwnerDecl(zcu); |
| 2397 | const pt = o.pt; | 2488 | const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); |
| 2398 | const zcu = pt.zcu; | 2489 | try o.debug_type_map.put(gpa, ty, debug_struct_type); |
| 2399 | const ip = &zcu.intern_pool; | 2490 | return debug_struct_type; |
| | 2491 | } |
| 2400 | | 2492 | |
| 2401 | var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; | 2493 | const struct_type = zcu.typeToStruct(ty).?; |
| 2402 | defer fields.deinit(gpa); | | |
| 2403 | | 2494 | |
| 2404 | const unresolved = &o.debug_unresolved_namespace_scopes; | 2495 | var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; |
| 2405 | var unresolved_i: usize = 0; | 2496 | defer fields.deinit(gpa); |
| 2406 | while (unresolved_i < unresolved.count()) : (unresolved_i += 1) { | | |
| 2407 | const ty = unresolved.keys()[unresolved_i]; | | |
| 2408 | const required_by_runtime = unresolved.values()[unresolved_i]; | | |
| 2409 | | 2497 | |
| 2410 | const owner_decl_index = ty.getOwnerDeclOrNull(zcu); | 2498 | try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len); |
| 2411 | const owner_decl: ?*Zcu.Decl = | | |
| 2412 | if (owner_decl_index) |owner| ip.declPtr(owner) else null; | | |
| 2413 | | 2499 | |
| 2414 | const file = if (owner_decl) |owner| | 2500 | const debug_fwd_ref = try o.builder.debugForwardReference(); |
| 2415 | try o.getDebugFile(zcu.namespacePtr(owner.src_namespace).fileScope(zcu)) | | |
| 2416 | else | | |
| 2417 | .none; | | |
| 2418 | const scope = if (owner_decl) |owner| | | |
| 2419 | try o.namespaceToDebugScope(owner.src_namespace) | | |
| 2420 | else | | |
| 2421 | o.debug_compile_unit; | | |
| 2422 | const line = if (owner_decl) |owner| owner.typeSrcLine(zcu) + 1 else 0; | | |
| 2423 | | 2501 | |
| 2424 | const name = if (owner_decl) |owner| owner.name.toSlice(ip) else try o.allocTypeName(ty); | 2502 | // Set as forward reference while the type is lowered in case it references itself |
| 2425 | defer if (owner_decl == null) gpa.free(name); | 2503 | try o.debug_type_map.put(gpa, ty, debug_fwd_ref); |
| 2426 | | 2504 | |
| 2427 | const fwd_ref = o.debug_type_map.get(ty).?; | 2505 | comptime assert(struct_layout_version == 2); |
| | 2506 | var it = struct_type.iterateRuntimeOrder(ip); |
| | 2507 | while (it.next()) |field_index| { |
| | 2508 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| | 2509 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| | 2510 | const field_size = field_ty.abiSize(pt); |
| | 2511 | const field_align = pt.structFieldAlignment( |
| | 2512 | struct_type.fieldAlign(ip, field_index), |
| | 2513 | field_ty, |
| | 2514 | struct_type.layout, |
| | 2515 | ); |
| | 2516 | const field_offset = ty.structFieldOffset(field_index, pt); |
| 2428 | | 2517 | |
| 2429 | fields.clearRetainingCapacity(); | 2518 | const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse |
| | 2519 | try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); |
| 2430 | | 2520 | |
| 2431 | const ns = if (ty.getNamespace(zcu)) |n| n.unwrap() else null; | 2521 | fields.appendAssumeCapacity(try o.builder.debugMemberType( |
| 2432 | if (ns) |ns_id| { | 2522 | try o.builder.metadataString(field_name.toSlice(ip)), |
| 2433 | const namespace = ip.namespacePtr(ns_id); | 2523 | .none, // File |
| 2434 | try fields.ensureUnusedCapacity(gpa, namespace.decls.keys().len); | 2524 | debug_fwd_ref, |
| | 2525 | 0, // Line |
| | 2526 | try o.lowerDebugType(field_ty), |
| | 2527 | field_size * 8, |
| | 2528 | (field_align.toByteUnits() orelse 0) * 8, |
| | 2529 | field_offset * 8, |
| | 2530 | )); |
| | 2531 | } |
| 2435 | | 2532 | |
| 2436 | for (namespace.decls.keys()) |decl_id| { | 2533 | const debug_struct_type = try o.builder.debugStructType( |
| 2437 | const decl = ip.declPtr(decl_id); | 2534 | try o.builder.metadataString(name), |
| 2438 | const decl_name = decl.name.toSlice(ip); | 2535 | .none, // File |
| | 2536 | o.debug_compile_unit, // Scope |
| | 2537 | 0, // Line |
| | 2538 | .none, // Underlying type |
| | 2539 | ty.abiSize(pt) * 8, |
| | 2540 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| | 2541 | try o.builder.debugTuple(fields.items), |
| | 2542 | ); |
| 2439 | | 2543 | |
| 2440 | if (!decl.has_tv) continue; | 2544 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type); |
| 2441 | if (decl.kind != .named) continue; | | |
| 2442 | if (decl.analysis != .complete) continue; | | |
| 2443 | | 2545 | |
| 2444 | const decl_line = 0; | 2546 | // Set to real type now that it has been lowered fully |
| | 2547 | const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; |
| | 2548 | map_ptr.* = debug_struct_type; |
| 2445 | | 2549 | |
| 2446 | if (decl.val.typeOf(zcu).ip_index == .type_type) { | 2550 | return debug_struct_type; |
| 2447 | const nested_type = decl.val.toType(); | 2551 | }, |
| 2448 | // If this decl is the owner of the type, it will | 2552 | .Union => { |
| 2449 | // already have been declared as a direct child and | 2553 | const owner_decl_index = ty.getOwnerDecl(zcu); |
| 2450 | // will not need to be typedef'd. | | |
| 2451 | if (nested_type.getOwnerDeclOrNull(zcu)) |owner| { | | |
| 2452 | if (owner == decl_id) continue; | | |
| 2453 | } | | |
| 2454 | | 2554 | |
| 2455 | switch (nested_type.zigTypeTag(zcu)) { | 2555 | const name = try o.allocTypeName(ty); |
| 2456 | // We still may want these for a Zig expression | 2556 | defer gpa.free(name); |
| 2457 | // evaluator in debuggers, but for now they are | | |
| 2458 | // completely useless. | | |
| 2459 | .ComptimeInt, .ComptimeFloat, .Type, .Undefined, .Null, .EnumLiteral => continue, | | |
| 2460 | else => {}, | | |
| 2461 | } | | |
| 2462 | | 2557 | |
| 2463 | fields.appendAssumeCapacity(try o.builder.debugTypedef( | 2558 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 2464 | try o.builder.metadataString(decl_name), | 2559 | if (!union_type.haveFieldTypes(ip) or |
| 2465 | try o.getDebugFile(namespace.fileScope(zcu)), | 2560 | !ty.hasRuntimeBitsIgnoreComptime(pt) or |
| 2466 | fwd_ref, | 2561 | !union_type.haveLayout(ip)) |
| 2467 | decl_line, | 2562 | { |
| 2468 | try o.lowerDebugType(nested_type, false), | 2563 | const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); |
| 2469 | 0, // Align | 2564 | try o.debug_type_map.put(gpa, ty, debug_union_type); |
| 2470 | )); | 2565 | return debug_union_type; |
| 2471 | } | | |
| 2472 | } | 2566 | } |
| 2473 | } | | |
| 2474 | | 2567 | |
| 2475 | if (!required_by_runtime) { | 2568 | const layout = pt.getUnionLayout(union_type); |
| 2476 | const res = try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); | | |
| 2477 | o.builder.debugForwardReferenceSetType(fwd_ref, res); | | |
| 2478 | continue; | | |
| 2479 | } | | |
| 2480 | | | |
| 2481 | const res = switch (ty.zigTypeTag(zcu)) { | | |
| 2482 | .Enum => res: { | | |
| 2483 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { | | |
| 2484 | break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); | | |
| 2485 | } | | |
| 2486 | | | |
| 2487 | const enum_type = ip.loadEnumType(ty.toIntern()); | | |
| 2488 | | | |
| 2489 | const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len); | | |
| 2490 | defer gpa.free(enumerators); | | |
| 2491 | | 2569 | |
| 2492 | const int_ty = Type.fromInterned(enum_type.tag_ty); | 2570 | const debug_fwd_ref = try o.builder.debugForwardReference(); |
| 2493 | const int_info = ty.intInfo(zcu); | | |
| 2494 | assert(int_info.bits != 0); | | |
| 2495 | | | |
| 2496 | for (enum_type.names.get(ip), 0..) |field_name_ip, i| { | | |
| 2497 | var bigint_space: Value.BigIntSpace = undefined; | | |
| 2498 | const bigint = if (enum_type.values.len != 0) | | |
| 2499 | Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt) | | |
| 2500 | else | | |
| 2501 | std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst(); | | |
| 2502 | | 2571 | |
| 2503 | enumerators[i] = try o.builder.debugEnumerator( | 2572 | // Set as forward reference while the type is lowered in case it references itself |
| 2504 | try o.builder.metadataString(field_name_ip.toSlice(ip)), | 2573 | try o.debug_type_map.put(gpa, ty, debug_fwd_ref); |
| 2505 | int_info.signedness == .unsigned, | | |
| 2506 | int_info.bits, | | |
| 2507 | bigint, | | |
| 2508 | ); | | |
| 2509 | } | | |
| 2510 | | 2574 | |
| 2511 | const debug_enum_type = try o.builder.debugEnumerationType( | 2575 | if (layout.payload_size == 0) { |
| | 2576 | const debug_union_type = try o.builder.debugStructType( |
| 2512 | try o.builder.metadataString(name), | 2577 | try o.builder.metadataString(name), |
| 2513 | file, | 2578 | .none, // File |
| 2514 | scope, | 2579 | o.debug_compile_unit, // Scope |
| 2515 | line, | 2580 | 0, // Line |
| 2516 | try o.lowerDebugType(int_ty, required_by_runtime), | 2581 | .none, // Underlying type |
| 2517 | ty.abiSize(pt) * 8, | 2582 | ty.abiSize(pt) * 8, |
| 2518 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | 2583 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2519 | try o.builder.debugTuple(enumerators), | 2584 | try o.builder.debugTuple( |
| | 2585 | &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))}, |
| | 2586 | ), |
| 2520 | ); | 2587 | ); |
| 2521 | | 2588 | |
| 2522 | try o.debug_enums.append(gpa, debug_enum_type); | 2589 | // Set to real type now that it has been lowered fully |
| 2523 | break :res debug_enum_type; | 2590 | const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; |
| 2524 | }, | 2591 | map_ptr.* = debug_union_type; |
| 2525 | .Opaque => res: { | | |
| 2526 | if (ty.toIntern() == .anyopaque_type) { | | |
| 2527 | break :res try o.builder.debugSignedType( | | |
| 2528 | try o.builder.metadataString("anyopaque"), | | |
| 2529 | 0, | | |
| 2530 | ); | | |
| 2531 | } | | |
| 2532 | | | |
| 2533 | const debug_opaque_type = try o.builder.debugStructType( | | |
| 2534 | try o.builder.metadataString(name), | | |
| 2535 | file, | | |
| 2536 | scope, | | |
| 2537 | line, | | |
| 2538 | .none, // Underlying type | | |
| 2539 | 0, // Size | | |
| 2540 | 0, // Align | | |
| 2541 | .none, // Fields | | |
| 2542 | false, // ByRef | | |
| 2543 | ); | | |
| 2544 | break :res debug_opaque_type; | | |
| 2545 | }, | | |
| 2546 | .Struct => res: { | | |
| 2547 | if (zcu.typeToPackedStruct(ty)) |struct_type| { | | |
| 2548 | const backing_int_ty = struct_type.backingIntTypeUnordered(ip); | | |
| 2549 | if (backing_int_ty != .none) { | | |
| 2550 | const info = Type.fromInterned(backing_int_ty).intInfo(zcu); | | |
| 2551 | const builder_name = try o.builder.metadataString(name); | | |
| 2552 | const debug_int_type = switch (info.signedness) { | | |
| 2553 | .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8), | | |
| 2554 | .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8), | | |
| 2555 | }; | | |
| 2556 | break :res debug_int_type; | | |
| 2557 | } | | |
| 2558 | } | | |
| 2559 | | 2592 | |
| 2560 | switch (ip.indexToKey(ty.toIntern())) { | 2593 | return debug_union_type; |
| 2561 | .anon_struct_type => |tuple| { | 2594 | } |
| 2562 | try fields.ensureUnusedCapacity(gpa, tuple.types.len); | | |
| 2563 | | | |
| 2564 | comptime assert(struct_layout_version == 2); | | |
| 2565 | var offset: u64 = 0; | | |
| 2566 | | | |
| 2567 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { | | |
| 2568 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; | | |
| 2569 | | | |
| 2570 | const field_size = Type.fromInterned(field_ty).abiSize(pt); | | |
| 2571 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); | | |
| 2572 | const field_offset = field_align.forward(offset); | | |
| 2573 | offset = field_offset + field_size; | | |
| 2574 | | | |
| 2575 | const field_name = if (tuple.names.len != 0) | | |
| 2576 | tuple.names.get(ip)[i].toSlice(ip) | | |
| 2577 | else | | |
| 2578 | try std.fmt.allocPrintZ(gpa, "{d}", .{i}); | | |
| 2579 | defer if (tuple.names.len == 0) gpa.free(field_name); | | |
| 2580 | | | |
| 2581 | fields.appendAssumeCapacity(try o.builder.debugMemberType( | | |
| 2582 | try o.builder.metadataString(field_name), | | |
| 2583 | .none, // File | | |
| 2584 | fwd_ref, | | |
| 2585 | 0, | | |
| 2586 | try o.lowerDebugType(Type.fromInterned(field_ty), required_by_runtime), | | |
| 2587 | field_size * 8, | | |
| 2588 | (field_align.toByteUnits() orelse 0) * 8, | | |
| 2589 | field_offset * 8, | | |
| 2590 | )); | | |
| 2591 | } | | |
| 2592 | | 2595 | |
| 2593 | const debug_struct_type = try o.builder.debugStructType( | 2596 | var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; |
| 2594 | try o.builder.metadataString(name), | 2597 | defer fields.deinit(gpa); |
| 2595 | file, | | |
| 2596 | scope, | | |
| 2597 | 0, // 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 | isByRef(ty, pt), | | |
| 2603 | ); | | |
| 2604 | | 2598 | |
| 2605 | break :res debug_struct_type; | 2599 | try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len); |
| 2606 | }, | | |
| 2607 | else => {}, | | |
| 2608 | } | | |
| 2609 | | 2600 | |
| 2610 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { | 2601 | const debug_union_fwd_ref = if (layout.tag_size == 0) |
| 2611 | break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); | 2602 | debug_fwd_ref |
| 2612 | } | 2603 | else |
| 2613 | const struct_type = zcu.typeToStruct(ty).?; | 2604 | try o.builder.debugForwardReference(); |
| 2614 | | 2605 | |
| 2615 | if (!struct_type.haveLayout(ip) or !struct_type.haveFieldTypes(ip)) { | 2606 | const tag_type = union_type.loadTagType(ip); |
| 2616 | break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); | | |
| 2617 | } | | |
| 2618 | | 2607 | |
| 2619 | try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len); | 2608 | for (0..tag_type.names.len) |field_index| { |
| | 2609 | const field_ty = union_type.field_types.get(ip)[field_index]; |
| | 2610 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 2620 | | 2611 | |
| 2621 | comptime assert(struct_layout_version == 2); | 2612 | const field_size = Type.fromInterned(field_ty).abiSize(pt); |
| 2622 | var it = struct_type.iterateRuntimeOrder(ip); | 2613 | const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) { |
| 2623 | while (it.next()) |field_index| { | 2614 | .@"packed" => .none, |
| 2624 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 2615 | .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)), |
| 2625 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | 2616 | }; |
| 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); | | |
| 2633 | | 2617 | |
| 2634 | const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse | 2618 | const field_name = tag_type.names.get(ip)[field_index]; |
| 2635 | try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); | 2619 | fields.appendAssumeCapacity(try o.builder.debugMemberType( |
| | 2620 | try o.builder.metadataString(field_name.toSlice(ip)), |
| | 2621 | .none, // File |
| | 2622 | debug_union_fwd_ref, |
| | 2623 | 0, // Line |
| | 2624 | try o.lowerDebugType(Type.fromInterned(field_ty)), |
| | 2625 | field_size * 8, |
| | 2626 | (field_align.toByteUnits() orelse 0) * 8, |
| | 2627 | 0, // Offset |
| | 2628 | )); |
| | 2629 | } |
| 2636 | | 2630 | |
| 2637 | fields.appendAssumeCapacity(try o.builder.debugMemberType( | 2631 | var union_name_buf: ?[:0]const u8 = null; |
| 2638 | try o.builder.metadataString(field_name.toSlice(ip)), | 2632 | defer if (union_name_buf) |buf| gpa.free(buf); |
| 2639 | file, | 2633 | const union_name = if (layout.tag_size == 0) name else name: { |
| 2640 | fwd_ref, | 2634 | union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name}); |
| 2641 | 0, // Line | 2635 | break :name union_name_buf.?; |
| 2642 | try o.lowerDebugType(field_ty, required_by_runtime), | 2636 | }; |
| 2643 | field_size * 8, | | |
| 2644 | (field_align.toByteUnits() orelse 0) * 8, | | |
| 2645 | field_offset * 8, | | |
| 2646 | )); | | |
| 2647 | } | | |
| 2648 | | 2637 | |
| 2649 | const debug_struct_type = try o.builder.debugStructType( | 2638 | const debug_union_type = try o.builder.debugUnionType( |
| 2650 | try o.builder.metadataString(name), | 2639 | try o.builder.metadataString(union_name), |
| 2651 | file, | 2640 | .none, // File |
| 2652 | scope, | 2641 | o.debug_compile_unit, // Scope |
| 2653 | line, | 2642 | 0, // Line |
| 2654 | .none, // Underlying type | 2643 | .none, // Underlying type |
| 2655 | ty.abiSize(pt) * 8, | 2644 | ty.abiSize(pt) * 8, |
| 2656 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | 2645 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2657 | try o.builder.debugTuple(fields.items), | 2646 | try o.builder.debugTuple(fields.items), |
| 2658 | isByRef(ty, pt), | 2647 | ); |
| 2659 | ); | | |
| 2660 | | 2648 | |
| 2661 | break :res debug_struct_type; | 2649 | o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type); |
| 2662 | }, | | |
| 2663 | .Union => res: { | | |
| 2664 | const union_type = ip.loadUnionType(ty.toIntern()); | | |
| 2665 | if (!union_type.haveFieldTypes(ip) or | | |
| 2666 | !ty.hasRuntimeBitsIgnoreComptime(pt) or | | |
| 2667 | !union_type.haveLayout(ip)) | | |
| 2668 | { | | |
| 2669 | break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); | | |
| 2670 | } | | |
| 2671 | | 2650 | |
| 2672 | const layout = pt.getUnionLayout(union_type); | 2651 | if (layout.tag_size == 0) { |
| | 2652 | // Set to real type now that it has been lowered fully |
| | 2653 | const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; |
| | 2654 | map_ptr.* = debug_union_type; |
| 2673 | | 2655 | |
| 2674 | if (layout.payload_size == 0) { | 2656 | return debug_union_type; |
| 2675 | const debug_union_type = try o.builder.debugStructType( | 2657 | } |
| 2676 | try o.builder.metadataString(name), | | |
| 2677 | file, | | |
| 2678 | scope, | | |
| 2679 | 0, // Line | | |
| 2680 | .none, // Underlying type | | |
| 2681 | ty.abiSize(pt) * 8, | | |
| 2682 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | | |
| 2683 | try o.builder.debugTuple( | | |
| 2684 | &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty), required_by_runtime)}, | | |
| 2685 | ), | | |
| 2686 | isByRef(ty, pt), | | |
| 2687 | ); | | |
| 2688 | | 2658 | |
| 2689 | break :res debug_union_type; | 2659 | var tag_offset: u64 = undefined; |
| 2690 | } | 2660 | var payload_offset: u64 = undefined; |
| | 2661 | if (layout.tag_align.compare(.gte, layout.payload_align)) { |
| | 2662 | tag_offset = 0; |
| | 2663 | payload_offset = layout.payload_align.forward(layout.tag_size); |
| | 2664 | } else { |
| | 2665 | payload_offset = 0; |
| | 2666 | tag_offset = layout.tag_align.forward(layout.payload_size); |
| | 2667 | } |
| 2691 | | 2668 | |
| 2692 | try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len); | 2669 | const debug_tag_type = try o.builder.debugMemberType( |
| | 2670 | try o.builder.metadataString("tag"), |
| | 2671 | .none, // File |
| | 2672 | debug_fwd_ref, |
| | 2673 | 0, // Line |
| | 2674 | try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty)), |
| | 2675 | layout.tag_size * 8, |
| | 2676 | (layout.tag_align.toByteUnits() orelse 0) * 8, |
| | 2677 | tag_offset * 8, |
| | 2678 | ); |
| 2693 | | 2679 | |
| 2694 | const debug_union_fwd_ref = if (layout.tag_size == 0) | 2680 | const debug_payload_type = try o.builder.debugMemberType( |
| 2695 | fwd_ref | 2681 | try o.builder.metadataString("payload"), |
| 2696 | else | 2682 | .none, // File |
| 2697 | try o.builder.debugForwardReference(); | 2683 | debug_fwd_ref, |
| | 2684 | 0, // Line |
| | 2685 | debug_union_type, |
| | 2686 | layout.payload_size * 8, |
| | 2687 | (layout.payload_align.toByteUnits() orelse 0) * 8, |
| | 2688 | payload_offset * 8, |
| | 2689 | ); |
| 2698 | | 2690 | |
| 2699 | const tag_type = union_type.loadTagType(ip); | 2691 | const full_fields: [2]Builder.Metadata = |
| | 2692 | if (layout.tag_align.compare(.gte, layout.payload_align)) |
| | 2693 | .{ debug_tag_type, debug_payload_type } |
| | 2694 | else |
| | 2695 | .{ debug_payload_type, debug_tag_type }; |
| 2700 | | 2696 | |
| 2701 | for (0..tag_type.names.len) |field_index| { | 2697 | const debug_tagged_union_type = try o.builder.debugStructType( |
| 2702 | const field_ty = union_type.field_types.get(ip)[field_index]; | 2698 | try o.builder.metadataString(name), |
| 2703 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; | 2699 | .none, // File |
| | 2700 | o.debug_compile_unit, // Scope |
| | 2701 | 0, // Line |
| | 2702 | .none, // Underlying type |
| | 2703 | ty.abiSize(pt) * 8, |
| | 2704 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| | 2705 | try o.builder.debugTuple(&full_fields), |
| | 2706 | ); |
| 2704 | | 2707 | |
| 2705 | const field_size = Type.fromInterned(field_ty).abiSize(pt); | 2708 | o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_tagged_union_type); |
| 2706 | const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) { | | |
| 2707 | .@"packed" => .none, | | |
| 2708 | .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)), | | |
| 2709 | }; | | |
| 2710 | | 2709 | |
| 2711 | const field_name = tag_type.names.get(ip)[field_index]; | 2710 | // Set to real type now that it has been lowered fully |
| 2712 | fields.appendAssumeCapacity(try o.builder.debugMemberType( | 2711 | const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; |
| 2713 | try o.builder.metadataString(field_name.toSlice(ip)), | 2712 | map_ptr.* = debug_tagged_union_type; |
| 2714 | file, | | |
| 2715 | debug_union_fwd_ref, | | |
| 2716 | 0, // Line | | |
| 2717 | try o.lowerDebugType(Type.fromInterned(field_ty), required_by_runtime), | | |
| 2718 | field_size * 8, | | |
| 2719 | (field_align.toByteUnits() orelse 0) * 8, | | |
| 2720 | 0, // Offset | | |
| 2721 | )); | | |
| 2722 | } | | |
| 2723 | | 2713 | |
| 2724 | var union_name_buf: ?[:0]const u8 = null; | 2714 | return debug_tagged_union_type; |
| 2725 | defer if (union_name_buf) |buf| gpa.free(buf); | 2715 | }, |
| 2726 | const union_name = if (layout.tag_size == 0) name else name: { | 2716 | .Fn => { |
| 2727 | union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name}); | 2717 | const fn_info = zcu.typeToFunc(ty).?; |
| 2728 | break :name union_name_buf.?; | | |
| 2729 | }; | | |
| 2730 | | 2718 | |
| 2731 | const debug_union_type = try o.builder.debugUnionType( | 2719 | var debug_param_types = std.ArrayList(Builder.Metadata).init(gpa); |
| 2732 | try o.builder.metadataString(union_name), | 2720 | defer debug_param_types.deinit(); |
| 2733 | file, | | |
| 2734 | scope, | | |
| 2735 | line, | | |
| 2736 | .none, // Underlying type | | |
| 2737 | ty.abiSize(pt) * 8, | | |
| 2738 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | | |
| 2739 | try o.builder.debugTuple(fields.items), | | |
| 2740 | isByRef(ty, pt), | | |
| 2741 | ); | | |
| 2742 | | 2721 | |
| 2743 | if (layout.tag_size == 0) { | 2722 | try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len); |
| 2744 | break :res debug_union_type; | | |
| 2745 | } | | |
| 2746 | | 2723 | |
| 2747 | o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type); | 2724 | // Return type goes first. |
| | 2725 | if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) { |
| | 2726 | const sret = firstParamSRet(fn_info, pt, target); |
| | 2727 | const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type); |
| | 2728 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty)); |
| 2748 | | 2729 | |
| 2749 | var tag_offset: u64 = undefined; | 2730 | if (sret) { |
| 2750 | var payload_offset: u64 = undefined; | 2731 | const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type)); |
| 2751 | if (layout.tag_align.compare(.gte, layout.payload_align)) { | 2732 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); |
| 2752 | tag_offset = 0; | | |
| 2753 | payload_offset = layout.payload_align.forward(layout.tag_size); | | |
| 2754 | } else { | | |
| 2755 | payload_offset = 0; | | |
| 2756 | tag_offset = layout.tag_align.forward(layout.payload_size); | | |
| 2757 | } | 2733 | } |
| | 2734 | } else { |
| | 2735 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void)); |
| | 2736 | } |
| 2758 | | 2737 | |
| 2759 | const debug_tag_type = try o.builder.debugMemberType( | 2738 | if (Type.fromInterned(fn_info.return_type).isError(zcu) and |
| 2760 | try o.builder.metadataString("tag"), | 2739 | zcu.comp.config.any_error_tracing) |
| 2761 | file, // File | 2740 | { |
| 2762 | fwd_ref, | 2741 | const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType()); |
| 2763 | 0, // Line | 2742 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); |
| 2764 | try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty), required_by_runtime), | 2743 | } |
| 2765 | layout.tag_size * 8, | | |
| 2766 | (layout.tag_align.toByteUnits() orelse 0) * 8, | | |
| 2767 | tag_offset * 8, | | |
| 2768 | ); | | |
| 2769 | | 2744 | |
| 2770 | const debug_payload_type = try o.builder.debugMemberType( | 2745 | for (0..fn_info.param_types.len) |i| { |
| 2771 | try o.builder.metadataString("payload"), | 2746 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]); |
| 2772 | file, | 2747 | if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 2773 | fwd_ref, | | |
| 2774 | 0, // Line | | |
| 2775 | debug_union_type, | | |
| 2776 | layout.payload_size * 8, | | |
| 2777 | (layout.payload_align.toByteUnits() orelse 0) * 8, | | |
| 2778 | payload_offset * 8, | | |
| 2779 | ); | | |
| 2780 | | 2748 | |
| 2781 | const full_fields: [2]Builder.Metadata = | 2749 | if (isByRef(param_ty, pt)) { |
| 2782 | if (layout.tag_align.compare(.gte, layout.payload_align)) | 2750 | const ptr_ty = try pt.singleMutPtrType(param_ty); |
| 2783 | .{ debug_tag_type, debug_payload_type } | 2751 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); |
| 2784 | else | 2752 | } else { |
| 2785 | .{ debug_payload_type, debug_tag_type }; | 2753 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty)); |
| | 2754 | } |
| | 2755 | } |
| 2786 | | 2756 | |
| 2787 | const debug_tagged_union_type = try o.builder.debugStructType( | 2757 | const debug_function_type = try o.builder.debugSubroutineType( |
| 2788 | try o.builder.metadataString(name), | 2758 | try o.builder.debugTuple(debug_param_types.items), |
| 2789 | file, // File | 2759 | ); |
| 2790 | scope, | | |
| 2791 | line, | | |
| 2792 | .none, // Underlying type | | |
| 2793 | ty.abiSize(pt) * 8, | | |
| 2794 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | | |
| 2795 | try o.builder.debugTuple(&full_fields), | | |
| 2796 | isByRef(ty, pt), | | |
| 2797 | ); | | |
| 2798 | | 2760 | |
| 2799 | break :res debug_tagged_union_type; | 2761 | try o.debug_type_map.put(gpa, ty, debug_function_type); |
| 2800 | }, | 2762 | return debug_function_type; |
| 2801 | else => unreachable, // Handled above. | 2763 | }, |
| 2802 | }; | 2764 | .ComptimeInt => unreachable, |
| | 2765 | .ComptimeFloat => unreachable, |
| | 2766 | .Type => unreachable, |
| | 2767 | .Undefined => unreachable, |
| | 2768 | .Null => unreachable, |
| | 2769 | .EnumLiteral => unreachable, |
| 2803 | | 2770 | |
| 2804 | o.builder.debugForwardReferenceSetType(fwd_ref, res); | 2771 | .Frame => @panic("TODO implement lowerDebugType for Frame types"), |
| | 2772 | .AnyFrame => @panic("TODO implement lowerDebugType for AnyFrame types"), |
| 2805 | } | 2773 | } |
| 2806 | } | 2774 | } |
| 2807 | | 2775 | |
| ... | @@ -2811,10 +2779,14 @@ pub const Object = struct { | ... | @@ -2811,10 +2779,14 @@ pub const Object = struct { |
| 2811 | const file_scope = namespace.fileScope(zcu); | 2779 | const file_scope = namespace.fileScope(zcu); |
| 2812 | if (namespace.parent == .none) return try o.getDebugFile(file_scope); | 2780 | if (namespace.parent == .none) return try o.getDebugFile(file_scope); |
| 2813 | | 2781 | |
| 2814 | return o.lowerDebugType(zcu.declPtr(namespace.decl_index).val.toType(), false); | 2782 | const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index); |
| | 2783 | |
| | 2784 | if (!gop.found_existing) gop.value_ptr.* = try o.builder.debugForwardReference(); |
| | 2785 | |
| | 2786 | return gop.value_ptr.*; |
| 2815 | } | 2787 | } |
| 2816 | | 2788 | |
| 2817 | fn makeNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex, fields: []const Builder.Metadata) !Builder.Metadata { | 2789 | fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata { |
| 2818 | const zcu = o.pt.zcu; | 2790 | const zcu = o.pt.zcu; |
| 2819 | const decl = zcu.declPtr(decl_index); | 2791 | const decl = zcu.declPtr(decl_index); |
| 2820 | const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); | 2792 | const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); |
| ... | @@ -2826,8 +2798,7 @@ pub const Object = struct { | ... | @@ -2826,8 +2798,7 @@ pub const Object = struct { |
| 2826 | .none, | 2798 | .none, |
| 2827 | 0, | 2799 | 0, |
| 2828 | 0, | 2800 | 0, |
| 2829 | if (fields.len == 0) .none else try o.builder.debugTuple(fields), | 2801 | .none, |
| 2830 | false, // is_byref | | |
| 2831 | ); | 2802 | ); |
| 2832 | } | 2803 | } |
| 2833 | | 2804 | |
| ... | @@ -4741,33 +4712,16 @@ pub const DeclGen = struct { | ... | @@ -4741,33 +4712,16 @@ pub const DeclGen = struct { |
| 4741 | if (!owner_mod.strip) { | 4712 | if (!owner_mod.strip) { |
| 4742 | const debug_file = try o.getDebugFile(file_scope); | 4713 | const debug_file = try o.getDebugFile(file_scope); |
| 4743 | | 4714 | |
| 4744 | const linkage_name = try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)); | | |
| 4745 | const is_internal_linkage = !decl.isExtern(zcu); | | |
| 4746 | | | |
| 4747 | const ty = try o.lowerDebugType(decl.typeOf(zcu), true); | | |
| 4748 | const debug_global_var = try o.builder.debugGlobalVar( | 4715 | const debug_global_var = try o.builder.debugGlobalVar( |
| 4749 | linkage_name, | 4716 | try o.builder.metadataString(decl.name.toSlice(ip)), // Name |
| 4750 | linkage_name, | 4717 | try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name |
| 4751 | debug_file, | 4718 | debug_file, // File |
| 4752 | debug_file, | 4719 | debug_file, // Scope |
| 4753 | line_number, | 4720 | line_number, |
| 4754 | ty, | 4721 | try o.lowerDebugType(decl.typeOf(zcu)), |
| 4755 | variable_index, | 4722 | variable_index, |
| 4756 | is_internal_linkage, | 4723 | .{ .local = !decl.isExtern(zcu) }, |
| 4757 | ); | 4724 | ); |
| 4758 | if (is_internal_linkage) { | | |
| 4759 | const name = try o.builder.metadataString(decl.name.toSlice(ip)); | | |
| 4760 | const debug_scope = try o.namespaceToDebugScope(decl.src_namespace); | | |
| 4761 | | | |
| 4762 | const import = try o.builder.debugImportDeclaration( | | |
| 4763 | name, | | |
| 4764 | debug_file, | | |
| 4765 | debug_scope, | | |
| 4766 | line_number, | | |
| 4767 | debug_global_var, | | |
| 4768 | ); | | |
| 4769 | try o.debug_imports.append(o.gpa, import); | | |
| 4770 | } | | |
| 4771 | | 4725 | |
| 4772 | const debug_expression = try o.builder.debugExpression(&.{}); | 4726 | const debug_expression = try o.builder.debugExpression(&.{}); |
| 4773 | | 4727 | |
| ... | @@ -5218,12 +5172,11 @@ pub const FuncGen = struct { | ... | @@ -5218,12 +5172,11 @@ pub const FuncGen = struct { |
| 5218 | | 5172 | |
| 5219 | self.scope = try o.builder.debugSubprogram( | 5173 | self.scope = try o.builder.debugSubprogram( |
| 5220 | self.file, | 5174 | self.file, |
| 5221 | self.file, // TODO Get the correct scope into here—self.scope is the function's *inner* scope. | | |
| 5222 | try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)), | 5175 | try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)), |
| 5223 | try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)), | 5176 | try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)), |
| 5224 | line_number, | 5177 | line_number, |
| 5225 | line_number + func.lbrace_line, | 5178 | line_number + func.lbrace_line, |
| 5226 | try o.lowerDebugType(fn_ty, true), | 5179 | try o.lowerDebugType(fn_ty), |
| 5227 | .{ | 5180 | .{ |
| 5228 | .di_flags = .{ .StaticMember = true }, | 5181 | .di_flags = .{ .StaticMember = true }, |
| 5229 | .sp_flags = .{ | 5182 | .sp_flags = .{ |
| ... | @@ -6773,7 +6726,7 @@ pub const FuncGen = struct { | ... | @@ -6773,7 +6726,7 @@ pub const FuncGen = struct { |
| 6773 | self.file, | 6726 | self.file, |
| 6774 | self.scope, | 6727 | self.scope, |
| 6775 | self.prev_dbg_line, | 6728 | self.prev_dbg_line, |
| 6776 | try o.lowerDebugType(ptr_ty.childType(mod), true), | 6729 | try o.lowerDebugType(ptr_ty.childType(mod)), |
| 6777 | ); | 6730 | ); |
| 6778 | | 6731 | |
| 6779 | _ = try self.wip.callIntrinsic( | 6732 | _ = try self.wip.callIntrinsic( |
| ... | @@ -6806,7 +6759,7 @@ pub const FuncGen = struct { | ... | @@ -6806,7 +6759,7 @@ pub const FuncGen = struct { |
| 6806 | self.file, | 6759 | self.file, |
| 6807 | self.scope, | 6760 | self.scope, |
| 6808 | self.prev_dbg_line, | 6761 | self.prev_dbg_line, |
| 6809 | try o.lowerDebugType(operand_ty, true), | 6762 | try o.lowerDebugType(operand_ty), |
| 6810 | ); | 6763 | ); |
| 6811 | | 6764 | |
| 6812 | const pt = o.pt; | 6765 | const pt = o.pt; |
| ... | @@ -8920,7 +8873,7 @@ pub const FuncGen = struct { | ... | @@ -8920,7 +8873,7 @@ pub const FuncGen = struct { |
| 8920 | self.file, | 8873 | self.file, |
| 8921 | self.scope, | 8874 | self.scope, |
| 8922 | lbrace_line, | 8875 | lbrace_line, |
| 8923 | try o.lowerDebugType(inst_ty, true), | 8876 | try o.lowerDebugType(inst_ty), |
| 8924 | @intCast(self.arg_index), | 8877 | @intCast(self.arg_index), |
| 8925 | ); | 8878 | ); |
| 8926 | | 8879 | |