diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 6780e17e1e..bc7023eae2 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -2459,24 +2459,13 @@ pub const ModuleDebugInfo = switch (native_os) { module, relocated_address - coff_section.virtual_address, ) orelse "???"; - // While DWARF gets us just the function's own name, the PDB - // stores it qualified with its namespace by the C++ `::` - // operator. We can strip that for consistency; the - // SymbolInfo will contain the line number, which is a more - // language-neutral way of distinguishing same-named symbols - // anyway. - const symbol_simple_name = if (mem.indexOf(u8, symbol_name, "::")) |cpp_namespace| - symbol_name[cpp_namespace + 2 ..] - else - symbol_name; - const opt_line_info = try self.pdb.?.getLineNumberInfo( module, relocated_address - coff_section.virtual_address, ); return SymbolInfo{ - .symbol_name = symbol_simple_name, + .symbol_name = symbol_name, .compile_unit_name = obj_basename, .line_info = opt_line_info, }; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index f3898247f3..a126897614 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -806,17 +806,14 @@ pub const Object = struct { debug_enums_fwd_ref: Builder.Metadata, debug_globals_fwd_ref: Builder.Metadata, - debug_imports_fwd_ref: Builder.Metadata, debug_enums: std.ArrayListUnmanaged(Builder.Metadata), debug_globals: std.ArrayListUnmanaged(Builder.Metadata), - debug_imports: std.ArrayListUnmanaged(Builder.Metadata), debug_file_map: std.AutoHashMapUnmanaged(*const Zcu.File, Builder.Metadata), debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata), - // The value says whether this namespace's type is runtime-required. - debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(Type, bool), + debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata), target: std.Target, /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function, @@ -881,7 +878,7 @@ pub const Object = struct { builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }}); - const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref, const debug_imports_fwd_ref = + const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref = if (!builder.strip) debug_info: { // We fully resolve all paths at this point to avoid lack of @@ -913,7 +910,6 @@ pub const Object = struct { const debug_enums_fwd_ref = try builder.debugForwardReference(); const debug_globals_fwd_ref = try builder.debugForwardReference(); - const debug_imports_fwd_ref = try builder.debugForwardReference(); const debug_compile_unit = try builder.debugCompileUnit( debug_file, @@ -926,7 +922,6 @@ pub const Object = struct { }), debug_enums_fwd_ref, debug_globals_fwd_ref, - debug_imports_fwd_ref, .{ .optimized = comp.root_mod.optimize_mode != .Debug }, ); @@ -982,8 +977,8 @@ pub const Object = struct { } try builder.debugNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit}); - break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref, debug_imports_fwd_ref }; - } else .{.none} ** 4; + break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref }; + } else .{.none} ** 3; const obj = try arena.create(Object); obj.* = .{ @@ -996,10 +991,8 @@ pub const Object = struct { .debug_compile_unit = debug_compile_unit, .debug_enums_fwd_ref = debug_enums_fwd_ref, .debug_globals_fwd_ref = debug_globals_fwd_ref, - .debug_imports_fwd_ref = debug_imports_fwd_ref, .debug_enums = .{}, .debug_globals = .{}, - .debug_imports = .{}, .debug_file_map = .{}, .debug_type_map = .{}, .debug_unresolved_namespace_scopes = .{}, @@ -1141,7 +1134,18 @@ pub const Object = struct { try self.genModuleLevelAssembly(); if (!self.builder.strip) { - try self.genNamespaces(); + { + var i: usize = 0; + while (i < self.debug_unresolved_namespace_scopes.count()) : (i += 1) { + const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i]; + const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i]; + + const namespace = zcu.namespacePtr(namespace_index); + const debug_type = try self.lowerDebugType(namespace.getType(zcu)); + + self.builder.debugForwardReferenceSetType(fwd_ref, debug_type); + } + } self.builder.debugForwardReferenceSetType( self.debug_enums_fwd_ref, @@ -1152,11 +1156,6 @@ pub const Object = struct { self.debug_globals_fwd_ref, try self.builder.debugTuple(self.debug_globals.items), ); - - self.builder.debugForwardReferenceSetType( - self.debug_imports_fwd_ref, - try self.builder.debugTuple(self.debug_imports.items), - ); } } @@ -1636,19 +1635,15 @@ pub const Object = struct { const file, const subprogram = if (!wip.strip) debug_info: { const file = try o.getDebugFile(file_scope); - const scope = try o.lowerDebugType(zcu.declPtr(namespace.decl_index).val.toType(), false); const line_number = decl.navSrcLine(zcu) + 1; const is_internal_linkage = decl.val.getExternFunc(zcu) == null; - const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu), true); - const decl_name = try o.builder.metadataString(decl.name.toSlice(ip)); - const link_name = try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)); + const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu)); const subprogram = try o.builder.debugSubprogram( file, - scope, - decl_name, - link_name, + try o.builder.metadataString(decl.name.toSlice(ip)), + try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)), line_number, line_number + func.lbrace_line, debug_decl_type, @@ -1665,7 +1660,6 @@ pub const Object = struct { }, o.debug_compile_unit, ); - function_index.setSubprogram(subprogram, &o.builder); break :debug_info .{ file, subprogram }; } else .{.none} ** 2; @@ -1913,7 +1907,6 @@ pub const Object = struct { pub fn lowerDebugType( o: *Object, ty: Type, - required_by_runtime: bool, ) Allocator.Error!Builder.Metadata { assert(!o.builder.strip); @@ -1923,13 +1916,7 @@ pub const Object = struct { const zcu = pt.zcu; const ip = &zcu.intern_pool; - if (o.debug_type_map.get(ty)) |debug_type| { - if (required_by_runtime) { - if (o.debug_unresolved_namespace_scopes.getEntry(ty)) |entry| - entry.value_ptr.* = true; - } - return debug_type; - } + if (o.debug_type_map.get(ty)) |debug_type| return debug_type; switch (ty.zigTypeTag(zcu)) { .Void, @@ -1944,9 +1931,10 @@ pub const Object = struct { }, .Int => { const info = ty.intInfo(zcu); - const int_name = try o.allocTypeName(ty); - defer gpa.free(int_name); - const builder_name = try o.builder.metadataString(int_name); + assert(info.bits != 0); + const name = try o.allocTypeName(ty); + defer gpa.free(name); + const builder_name = try o.builder.metadataString(name); const debug_bits = ty.abiSize(pt) * 8; // lldb cannot handle non-byte sized types const debug_int_type = switch (info.signedness) { .signed => try o.builder.debugSignedType(builder_name, debug_bits), @@ -1955,12 +1943,68 @@ pub const Object = struct { try o.debug_type_map.put(gpa, ty, debug_int_type); return debug_int_type; }, + .Enum => { + const owner_decl_index = ty.getOwnerDecl(zcu); + const owner_decl = zcu.declPtr(owner_decl_index); + + if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { + const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); + try o.debug_type_map.put(gpa, ty, debug_enum_type); + return debug_enum_type; + } + + const enum_type = ip.loadEnumType(ty.toIntern()); + + const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len); + defer gpa.free(enumerators); + + const int_ty = Type.fromInterned(enum_type.tag_ty); + const int_info = ty.intInfo(zcu); + assert(int_info.bits != 0); + + for (enum_type.names.get(ip), 0..) |field_name_ip, i| { + var bigint_space: Value.BigIntSpace = undefined; + const bigint = if (enum_type.values.len != 0) + Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt) + else + std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst(); + + enumerators[i] = try o.builder.debugEnumerator( + try o.builder.metadataString(field_name_ip.toSlice(ip)), + int_info.signedness == .unsigned, + int_info.bits, + bigint, + ); + } + + const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu); + const file = try o.getDebugFile(file_scope); + const scope = try o.namespaceToDebugScope(owner_decl.src_namespace); + + const name = try o.allocTypeName(ty); + defer gpa.free(name); + + const debug_enum_type = try o.builder.debugEnumerationType( + try o.builder.metadataString(name), + file, + scope, + owner_decl.typeSrcLine(zcu) + 1, // Line + try o.lowerDebugType(int_ty), + ty.abiSize(pt) * 8, + (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, + try o.builder.debugTuple(enumerators), + ); + + try o.debug_type_map.put(gpa, ty, debug_enum_type); + try o.debug_enums.append(gpa, debug_enum_type); + return debug_enum_type; + }, .Float => { const bits = ty.floatBits(target); - const float_name = try o.allocTypeName(ty); - defer gpa.free(float_name); + const name = try o.allocTypeName(ty); + defer gpa.free(name); const debug_float_type = try o.builder.debugFloatType( - try o.builder.metadataString(float_name), + try o.builder.metadataString(name), bits, ); try o.debug_type_map.put(gpa, ty, debug_float_type); @@ -2002,7 +2046,7 @@ pub const Object = struct { }, }, }); - const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty, required_by_runtime); + const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty); try o.debug_type_map.put(gpa, ty, debug_ptr_type); return debug_ptr_type; } @@ -2018,7 +2062,6 @@ pub const Object = struct { const name = try o.allocTypeName(ty); defer gpa.free(name); - const line = 0; const ptr_size = ptr_ty.abiSize(pt); @@ -2033,7 +2076,7 @@ pub const Object = struct { .none, // File debug_fwd_ref, 0, // Line - try o.lowerDebugType(ptr_ty, required_by_runtime), + try o.lowerDebugType(ptr_ty), ptr_size * 8, (ptr_align.toByteUnits() orelse 0) * 8, 0, // Offset @@ -2044,7 +2087,7 @@ pub const Object = struct { .none, // File debug_fwd_ref, 0, // Line - try o.lowerDebugType(len_ty, required_by_runtime), + try o.lowerDebugType(len_ty), len_size * 8, (len_align.toByteUnits() orelse 0) * 8, len_offset * 8, @@ -2062,7 +2105,6 @@ pub const Object = struct { debug_ptr_type, debug_len_type, }), - isByRef(ty, pt), ); o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_slice_type); @@ -2074,7 +2116,7 @@ pub const Object = struct { return debug_slice_type; } - const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child), required_by_runtime); + const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child)); const name = try o.allocTypeName(ty); defer gpa.free(name); @@ -2098,13 +2140,41 @@ pub const Object = struct { return debug_ptr_type; }, + .Opaque => { + if (ty.toIntern() == .anyopaque_type) { + const debug_opaque_type = try o.builder.debugSignedType( + try o.builder.metadataString("anyopaque"), + 0, + ); + try o.debug_type_map.put(gpa, ty, debug_opaque_type); + return debug_opaque_type; + } + + const name = try o.allocTypeName(ty); + defer gpa.free(name); + const owner_decl_index = ty.getOwnerDecl(zcu); + const owner_decl = zcu.declPtr(owner_decl_index); + const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu); + const debug_opaque_type = try o.builder.debugStructType( + try o.builder.metadataString(name), + try o.getDebugFile(file_scope), + try o.namespaceToDebugScope(owner_decl.src_namespace), + owner_decl.typeSrcLine(zcu) + 1, // Line + .none, // Underlying type + 0, // Size + 0, // Align + .none, // Fields + ); + try o.debug_type_map.put(gpa, ty, debug_opaque_type); + return debug_opaque_type; + }, .Array => { const debug_array_type = try o.builder.debugArrayType( .none, // Name .none, // File .none, // Scope 0, // Line - try o.lowerDebugType(ty.childType(zcu), required_by_runtime), + try o.lowerDebugType(ty.childType(zcu)), ty.abiSize(pt) * 8, (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&.{ @@ -2126,9 +2196,10 @@ pub const Object = struct { const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) { .Int => blk: { const info = elem_ty.intInfo(zcu); - const vec_name = try o.allocTypeName(ty); - defer gpa.free(vec_name); - const builder_name = try o.builder.metadataString(vec_name); + assert(info.bits != 0); + const name = try o.allocTypeName(ty); + defer gpa.free(name); + const builder_name = try o.builder.metadataString(name); break :blk switch (info.signedness) { .signed => try o.builder.debugSignedType(builder_name, info.bits), .unsigned => try o.builder.debugUnsignedType(builder_name, info.bits), @@ -2138,7 +2209,7 @@ pub const Object = struct { try o.builder.metadataString("bool"), 1, ), - else => try o.lowerDebugType(ty.childType(zcu), required_by_runtime), + else => try o.lowerDebugType(ty.childType(zcu)), }; const debug_vector_type = try o.builder.debugVectorType( @@ -2163,7 +2234,6 @@ pub const Object = struct { .Optional => { const name = try o.allocTypeName(ty); defer gpa.free(name); - const child_ty = ty.optionalChild(zcu); if (!child_ty.hasRuntimeBitsIgnoreComptime(pt)) { const debug_bool_type = try o.builder.debugBoolType( @@ -2180,7 +2250,7 @@ pub const Object = struct { try o.debug_type_map.put(gpa, ty, debug_fwd_ref); if (ty.optionalReprIsPayload(zcu)) { - const debug_optional_type = try o.lowerDebugType(child_ty, required_by_runtime); + const debug_optional_type = try o.lowerDebugType(child_ty); o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); @@ -2203,7 +2273,7 @@ pub const Object = struct { .none, // File debug_fwd_ref, 0, // Line - try o.lowerDebugType(child_ty, required_by_runtime), + try o.lowerDebugType(child_ty), payload_size * 8, (payload_align.toByteUnits() orelse 0) * 8, 0, // Offset @@ -2214,7 +2284,7 @@ pub const Object = struct { .none, debug_fwd_ref, 0, - try o.lowerDebugType(non_null_ty, required_by_runtime), + try o.lowerDebugType(non_null_ty), non_null_size * 8, (non_null_align.toByteUnits() orelse 0) * 8, non_null_offset * 8, @@ -2232,7 +2302,6 @@ pub const Object = struct { debug_data_type, debug_some_type, }), - isByRef(ty, pt), ); o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); @@ -2247,7 +2316,7 @@ pub const Object = struct { const payload_ty = ty.errorUnionPayload(zcu); if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { // TODO: Maybe remove? - const debug_error_union_type = try o.lowerDebugType(Type.anyerror, required_by_runtime); + const debug_error_union_type = try o.lowerDebugType(Type.anyerror); try o.debug_type_map.put(gpa, ty, debug_error_union_type); return debug_error_union_type; } @@ -2284,7 +2353,7 @@ pub const Object = struct { .none, // File debug_fwd_ref, 0, // Line - try o.lowerDebugType(Type.anyerror, required_by_runtime), + try o.lowerDebugType(Type.anyerror), error_size * 8, (error_align.toByteUnits() orelse 0) * 8, error_offset * 8, @@ -2294,7 +2363,7 @@ pub const Object = struct { .none, // File debug_fwd_ref, 0, // Line - try o.lowerDebugType(payload_ty, required_by_runtime), + try o.lowerDebugType(payload_ty), payload_size * 8, (payload_align.toByteUnits() orelse 0) * 8, payload_offset * 8, @@ -2309,7 +2378,6 @@ pub const Object = struct { ty.abiSize(pt) * 8, (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&fields), - isByRef(ty, pt), ); o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_error_union_type); @@ -2325,6 +2393,326 @@ pub const Object = struct { try o.debug_type_map.put(gpa, ty, debug_error_set); return debug_error_set; }, + .Struct => { + const name = try o.allocTypeName(ty); + defer gpa.free(name); + + if (zcu.typeToPackedStruct(ty)) |struct_type| { + const backing_int_ty = struct_type.backingIntTypeUnordered(ip); + if (backing_int_ty != .none) { + const info = Type.fromInterned(backing_int_ty).intInfo(zcu); + const builder_name = try o.builder.metadataString(name); + const debug_int_type = switch (info.signedness) { + .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8), + .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8), + }; + try o.debug_type_map.put(gpa, ty, debug_int_type); + return debug_int_type; + } + } + + switch (ip.indexToKey(ty.toIntern())) { + .anon_struct_type => |tuple| { + var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; + defer fields.deinit(gpa); + + try fields.ensureUnusedCapacity(gpa, tuple.types.len); + + comptime assert(struct_layout_version == 2); + var offset: u64 = 0; + + const debug_fwd_ref = try o.builder.debugForwardReference(); + + for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { + if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; + + const field_size = Type.fromInterned(field_ty).abiSize(pt); + const field_align = Type.fromInterned(field_ty).abiAlignment(pt); + const field_offset = field_align.forward(offset); + offset = field_offset + field_size; + + const field_name = if (tuple.names.len != 0) + tuple.names.get(ip)[i].toSlice(ip) + else + try std.fmt.allocPrintZ(gpa, "{d}", .{i}); + defer if (tuple.names.len == 0) gpa.free(field_name); + + fields.appendAssumeCapacity(try o.builder.debugMemberType( + try o.builder.metadataString(field_name), + .none, // File + debug_fwd_ref, + 0, + try o.lowerDebugType(Type.fromInterned(field_ty)), + field_size * 8, + (field_align.toByteUnits() orelse 0) * 8, + field_offset * 8, + )); + } + + const debug_struct_type = try o.builder.debugStructType( + try o.builder.metadataString(name), + .none, // File + o.debug_compile_unit, // Scope + 0, // Line + .none, // Underlying type + ty.abiSize(pt) * 8, + (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, + try o.builder.debugTuple(fields.items), + ); + + o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type); + + try o.debug_type_map.put(gpa, ty, debug_struct_type); + return debug_struct_type; + }, + .struct_type => { + if (!ip.loadStructType(ty.toIntern()).haveFieldTypes(ip)) { + // This can happen if a struct type makes it all the way to + // flush() without ever being instantiated or referenced (even + // via pointer). The only reason we are hearing about it now is + // that it is being used as a namespace to put other debug types + // into. Therefore we can satisfy this by making an empty namespace, + // rather than changing the frontend to unnecessarily resolve the + // struct field types. + const owner_decl_index = ty.getOwnerDecl(zcu); + const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); + try o.debug_type_map.put(gpa, ty, debug_struct_type); + return debug_struct_type; + } + }, + else => {}, + } + + if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { + const owner_decl_index = ty.getOwnerDecl(zcu); + const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); + try o.debug_type_map.put(gpa, ty, debug_struct_type); + return debug_struct_type; + } + + const struct_type = zcu.typeToStruct(ty).?; + + var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; + defer fields.deinit(gpa); + + try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len); + + const debug_fwd_ref = try o.builder.debugForwardReference(); + + // Set as forward reference while the type is lowered in case it references itself + try o.debug_type_map.put(gpa, ty, debug_fwd_ref); + + comptime assert(struct_layout_version == 2); + var it = struct_type.iterateRuntimeOrder(ip); + while (it.next()) |field_index| { + const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); + if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; + const field_size = field_ty.abiSize(pt); + const field_align = pt.structFieldAlignment( + struct_type.fieldAlign(ip, field_index), + field_ty, + struct_type.layout, + ); + const field_offset = ty.structFieldOffset(field_index, pt); + + const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse + try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); + + fields.appendAssumeCapacity(try o.builder.debugMemberType( + try o.builder.metadataString(field_name.toSlice(ip)), + .none, // File + debug_fwd_ref, + 0, // Line + try o.lowerDebugType(field_ty), + field_size * 8, + (field_align.toByteUnits() orelse 0) * 8, + field_offset * 8, + )); + } + + const debug_struct_type = try o.builder.debugStructType( + try o.builder.metadataString(name), + .none, // File + o.debug_compile_unit, // Scope + 0, // Line + .none, // Underlying type + ty.abiSize(pt) * 8, + (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, + try o.builder.debugTuple(fields.items), + ); + + o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type); + + // Set to real type now that it has been lowered fully + const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + map_ptr.* = debug_struct_type; + + return debug_struct_type; + }, + .Union => { + const owner_decl_index = ty.getOwnerDecl(zcu); + + const name = try o.allocTypeName(ty); + defer gpa.free(name); + + const union_type = ip.loadUnionType(ty.toIntern()); + if (!union_type.haveFieldTypes(ip) or + !ty.hasRuntimeBitsIgnoreComptime(pt) or + !union_type.haveLayout(ip)) + { + const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); + try o.debug_type_map.put(gpa, ty, debug_union_type); + return debug_union_type; + } + + const layout = pt.getUnionLayout(union_type); + + const debug_fwd_ref = try o.builder.debugForwardReference(); + + // Set as forward reference while the type is lowered in case it references itself + try o.debug_type_map.put(gpa, ty, debug_fwd_ref); + + if (layout.payload_size == 0) { + const debug_union_type = try o.builder.debugStructType( + try o.builder.metadataString(name), + .none, // File + o.debug_compile_unit, // Scope + 0, // Line + .none, // Underlying type + ty.abiSize(pt) * 8, + (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, + try o.builder.debugTuple( + &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))}, + ), + ); + + // Set to real type now that it has been lowered fully + const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + map_ptr.* = debug_union_type; + + return debug_union_type; + } + + var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; + defer fields.deinit(gpa); + + try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len); + + const debug_union_fwd_ref = if (layout.tag_size == 0) + debug_fwd_ref + else + try o.builder.debugForwardReference(); + + const tag_type = union_type.loadTagType(ip); + + for (0..tag_type.names.len) |field_index| { + const field_ty = union_type.field_types.get(ip)[field_index]; + if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; + + const field_size = Type.fromInterned(field_ty).abiSize(pt); + const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) { + .@"packed" => .none, + .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)), + }; + + const field_name = tag_type.names.get(ip)[field_index]; + fields.appendAssumeCapacity(try o.builder.debugMemberType( + try o.builder.metadataString(field_name.toSlice(ip)), + .none, // File + debug_union_fwd_ref, + 0, // Line + try o.lowerDebugType(Type.fromInterned(field_ty)), + field_size * 8, + (field_align.toByteUnits() orelse 0) * 8, + 0, // Offset + )); + } + + var union_name_buf: ?[:0]const u8 = null; + defer if (union_name_buf) |buf| gpa.free(buf); + const union_name = if (layout.tag_size == 0) name else name: { + union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name}); + break :name union_name_buf.?; + }; + + const debug_union_type = try o.builder.debugUnionType( + try o.builder.metadataString(union_name), + .none, // File + o.debug_compile_unit, // Scope + 0, // Line + .none, // Underlying type + ty.abiSize(pt) * 8, + (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, + try o.builder.debugTuple(fields.items), + ); + + o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type); + + if (layout.tag_size == 0) { + // Set to real type now that it has been lowered fully + const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + map_ptr.* = debug_union_type; + + return debug_union_type; + } + + var tag_offset: u64 = undefined; + var payload_offset: u64 = undefined; + if (layout.tag_align.compare(.gte, layout.payload_align)) { + tag_offset = 0; + payload_offset = layout.payload_align.forward(layout.tag_size); + } else { + payload_offset = 0; + tag_offset = layout.tag_align.forward(layout.payload_size); + } + + const debug_tag_type = try o.builder.debugMemberType( + try o.builder.metadataString("tag"), + .none, // File + debug_fwd_ref, + 0, // Line + try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty)), + layout.tag_size * 8, + (layout.tag_align.toByteUnits() orelse 0) * 8, + tag_offset * 8, + ); + + const debug_payload_type = try o.builder.debugMemberType( + try o.builder.metadataString("payload"), + .none, // File + debug_fwd_ref, + 0, // Line + debug_union_type, + layout.payload_size * 8, + (layout.payload_align.toByteUnits() orelse 0) * 8, + payload_offset * 8, + ); + + const full_fields: [2]Builder.Metadata = + if (layout.tag_align.compare(.gte, layout.payload_align)) + .{ debug_tag_type, debug_payload_type } + else + .{ debug_payload_type, debug_tag_type }; + + const debug_tagged_union_type = try o.builder.debugStructType( + try o.builder.metadataString(name), + .none, // File + o.debug_compile_unit, // Scope + 0, // Line + .none, // Underlying type + ty.abiSize(pt) * 8, + (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, + try o.builder.debugTuple(&full_fields), + ); + + o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_tagged_union_type); + + // Set to real type now that it has been lowered fully + const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + map_ptr.* = debug_tagged_union_type; + + return debug_tagged_union_type; + }, .Fn => { const fn_info = zcu.typeToFunc(ty).?; @@ -2337,21 +2725,21 @@ pub const Object = struct { if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) { const sret = firstParamSRet(fn_info, pt, target); const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type); - debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty, required_by_runtime)); + debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty)); if (sret) { const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type)); - debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime)); + debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); } } else { - debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void, required_by_runtime)); + debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void)); } if (Type.fromInterned(fn_info.return_type).isError(zcu) and zcu.comp.config.any_error_tracing) { const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType()); - debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime)); + debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); } for (0..fn_info.param_types.len) |i| { @@ -2360,9 +2748,9 @@ pub const Object = struct { if (isByRef(param_ty, pt)) { const ptr_ty = try pt.singleMutPtrType(param_ty); - debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime)); + debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); } else { - debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty, required_by_runtime)); + debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty)); } } @@ -2382,426 +2770,6 @@ pub const Object = struct { .Frame => @panic("TODO implement lowerDebugType for Frame types"), .AnyFrame => @panic("TODO implement lowerDebugType for AnyFrame types"), - // These are the types that need a correct scope. - .Enum, .Struct, .Union, .Opaque => {}, - } - const fwd_ref = try o.builder.debugForwardReference(); - try o.debug_type_map.put(gpa, ty, fwd_ref); - try o.debug_unresolved_namespace_scopes.put(gpa, ty, required_by_runtime); - - return fwd_ref; - } - - fn genNamespaces(o: *Object) !void { - const gpa = o.gpa; - const pt = o.pt; - const zcu = pt.zcu; - const ip = &zcu.intern_pool; - - var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; - defer fields.deinit(gpa); - - const unresolved = &o.debug_unresolved_namespace_scopes; - var unresolved_i: usize = 0; - while (unresolved_i < unresolved.count()) : (unresolved_i += 1) { - const ty = unresolved.keys()[unresolved_i]; - const required_by_runtime = unresolved.values()[unresolved_i]; - - const owner_decl_index = ty.getOwnerDeclOrNull(zcu); - const owner_decl: ?*Zcu.Decl = - if (owner_decl_index) |owner| ip.declPtr(owner) else null; - - const file = if (owner_decl) |owner| - try o.getDebugFile(zcu.namespacePtr(owner.src_namespace).fileScope(zcu)) - else - .none; - const scope = if (owner_decl) |owner| - try o.namespaceToDebugScope(owner.src_namespace) - else - o.debug_compile_unit; - const line = if (owner_decl) |owner| owner.typeSrcLine(zcu) + 1 else 0; - - const name = if (owner_decl) |owner| owner.name.toSlice(ip) else try o.allocTypeName(ty); - defer if (owner_decl == null) gpa.free(name); - - const fwd_ref = o.debug_type_map.get(ty).?; - - fields.clearRetainingCapacity(); - - const ns = if (ty.getNamespace(zcu)) |n| n.unwrap() else null; - if (ns) |ns_id| { - const namespace = ip.namespacePtr(ns_id); - try fields.ensureUnusedCapacity(gpa, namespace.decls.keys().len); - - for (namespace.decls.keys()) |decl_id| { - const decl = ip.declPtr(decl_id); - const decl_name = decl.name.toSlice(ip); - - if (!decl.has_tv) continue; - if (decl.kind != .named) continue; - if (decl.analysis != .complete) continue; - - const decl_line = 0; - - if (decl.val.typeOf(zcu).ip_index == .type_type) { - const nested_type = decl.val.toType(); - // If this decl is the owner of the type, it will - // already have been declared as a direct child and - // will not need to be typedef'd. - if (nested_type.getOwnerDeclOrNull(zcu)) |owner| { - if (owner == decl_id) continue; - } - - switch (nested_type.zigTypeTag(zcu)) { - // We still may want these for a Zig expression - // evaluator in debuggers, but for now they are - // completely useless. - .ComptimeInt, .ComptimeFloat, .Type, .Undefined, .Null, .EnumLiteral => continue, - else => {}, - } - - fields.appendAssumeCapacity(try o.builder.debugTypedef( - try o.builder.metadataString(decl_name), - try o.getDebugFile(namespace.fileScope(zcu)), - fwd_ref, - decl_line, - try o.lowerDebugType(nested_type, false), - 0, // Align - )); - } - } - } - - if (!required_by_runtime) { - const res = try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); - o.builder.debugForwardReferenceSetType(fwd_ref, res); - continue; - } - - const res = switch (ty.zigTypeTag(zcu)) { - .Enum => res: { - if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { - break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); - } - - const enum_type = ip.loadEnumType(ty.toIntern()); - - const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len); - defer gpa.free(enumerators); - - const int_ty = Type.fromInterned(enum_type.tag_ty); - const int_info = ty.intInfo(zcu); - assert(int_info.bits != 0); - - for (enum_type.names.get(ip), 0..) |field_name_ip, i| { - var bigint_space: Value.BigIntSpace = undefined; - const bigint = if (enum_type.values.len != 0) - Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt) - else - std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst(); - - enumerators[i] = try o.builder.debugEnumerator( - try o.builder.metadataString(field_name_ip.toSlice(ip)), - int_info.signedness == .unsigned, - int_info.bits, - bigint, - ); - } - - const debug_enum_type = try o.builder.debugEnumerationType( - try o.builder.metadataString(name), - file, - scope, - line, - try o.lowerDebugType(int_ty, required_by_runtime), - ty.abiSize(pt) * 8, - (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, - try o.builder.debugTuple(enumerators), - ); - - try o.debug_enums.append(gpa, debug_enum_type); - break :res debug_enum_type; - }, - .Opaque => res: { - if (ty.toIntern() == .anyopaque_type) { - break :res try o.builder.debugSignedType( - try o.builder.metadataString("anyopaque"), - 0, - ); - } - - const debug_opaque_type = try o.builder.debugStructType( - try o.builder.metadataString(name), - file, - scope, - line, - .none, // Underlying type - 0, // Size - 0, // Align - .none, // Fields - false, // ByRef - ); - break :res debug_opaque_type; - }, - .Struct => res: { - if (zcu.typeToPackedStruct(ty)) |struct_type| { - const backing_int_ty = struct_type.backingIntTypeUnordered(ip); - if (backing_int_ty != .none) { - const info = Type.fromInterned(backing_int_ty).intInfo(zcu); - const builder_name = try o.builder.metadataString(name); - const debug_int_type = switch (info.signedness) { - .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8), - .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8), - }; - break :res debug_int_type; - } - } - - switch (ip.indexToKey(ty.toIntern())) { - .anon_struct_type => |tuple| { - try fields.ensureUnusedCapacity(gpa, tuple.types.len); - - comptime assert(struct_layout_version == 2); - var offset: u64 = 0; - - for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { - if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; - - const field_size = Type.fromInterned(field_ty).abiSize(pt); - const field_align = Type.fromInterned(field_ty).abiAlignment(pt); - const field_offset = field_align.forward(offset); - offset = field_offset + field_size; - - const field_name = if (tuple.names.len != 0) - tuple.names.get(ip)[i].toSlice(ip) - else - try std.fmt.allocPrintZ(gpa, "{d}", .{i}); - defer if (tuple.names.len == 0) gpa.free(field_name); - - fields.appendAssumeCapacity(try o.builder.debugMemberType( - try o.builder.metadataString(field_name), - .none, // File - fwd_ref, - 0, - try o.lowerDebugType(Type.fromInterned(field_ty), required_by_runtime), - field_size * 8, - (field_align.toByteUnits() orelse 0) * 8, - field_offset * 8, - )); - } - - const debug_struct_type = try o.builder.debugStructType( - try o.builder.metadataString(name), - file, - scope, - 0, // Line - .none, // Underlying type - ty.abiSize(pt) * 8, - (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, - try o.builder.debugTuple(fields.items), - isByRef(ty, pt), - ); - - break :res debug_struct_type; - }, - else => {}, - } - - if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { - break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); - } - const struct_type = zcu.typeToStruct(ty).?; - - if (!struct_type.haveLayout(ip) or !struct_type.haveFieldTypes(ip)) { - break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); - } - - try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len); - - comptime assert(struct_layout_version == 2); - var it = struct_type.iterateRuntimeOrder(ip); - while (it.next()) |field_index| { - const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); - if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; - const field_size = field_ty.abiSize(pt); - const field_align = pt.structFieldAlignment( - struct_type.fieldAlign(ip, field_index), - field_ty, - struct_type.layout, - ); - const field_offset = ty.structFieldOffset(field_index, pt); - - const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse - try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); - - fields.appendAssumeCapacity(try o.builder.debugMemberType( - try o.builder.metadataString(field_name.toSlice(ip)), - file, - fwd_ref, - 0, // Line - try o.lowerDebugType(field_ty, required_by_runtime), - field_size * 8, - (field_align.toByteUnits() orelse 0) * 8, - field_offset * 8, - )); - } - - const debug_struct_type = try o.builder.debugStructType( - try o.builder.metadataString(name), - file, - scope, - line, - .none, // Underlying type - ty.abiSize(pt) * 8, - (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, - try o.builder.debugTuple(fields.items), - isByRef(ty, pt), - ); - - break :res debug_struct_type; - }, - .Union => res: { - const union_type = ip.loadUnionType(ty.toIntern()); - if (!union_type.haveFieldTypes(ip) or - !ty.hasRuntimeBitsIgnoreComptime(pt) or - !union_type.haveLayout(ip)) - { - break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items); - } - - const layout = pt.getUnionLayout(union_type); - - if (layout.payload_size == 0) { - const debug_union_type = try o.builder.debugStructType( - try o.builder.metadataString(name), - file, - scope, - 0, // Line - .none, // Underlying type - ty.abiSize(pt) * 8, - (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, - try o.builder.debugTuple( - &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty), required_by_runtime)}, - ), - isByRef(ty, pt), - ); - - break :res debug_union_type; - } - - try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len); - - const debug_union_fwd_ref = if (layout.tag_size == 0) - fwd_ref - else - try o.builder.debugForwardReference(); - - const tag_type = union_type.loadTagType(ip); - - for (0..tag_type.names.len) |field_index| { - const field_ty = union_type.field_types.get(ip)[field_index]; - if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; - - const field_size = Type.fromInterned(field_ty).abiSize(pt); - const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) { - .@"packed" => .none, - .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)), - }; - - const field_name = tag_type.names.get(ip)[field_index]; - fields.appendAssumeCapacity(try o.builder.debugMemberType( - try o.builder.metadataString(field_name.toSlice(ip)), - file, - debug_union_fwd_ref, - 0, // Line - try o.lowerDebugType(Type.fromInterned(field_ty), required_by_runtime), - field_size * 8, - (field_align.toByteUnits() orelse 0) * 8, - 0, // Offset - )); - } - - var union_name_buf: ?[:0]const u8 = null; - defer if (union_name_buf) |buf| gpa.free(buf); - const union_name = if (layout.tag_size == 0) name else name: { - union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name}); - break :name union_name_buf.?; - }; - - const debug_union_type = try o.builder.debugUnionType( - try o.builder.metadataString(union_name), - file, - scope, - line, - .none, // Underlying type - ty.abiSize(pt) * 8, - (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, - try o.builder.debugTuple(fields.items), - isByRef(ty, pt), - ); - - if (layout.tag_size == 0) { - break :res debug_union_type; - } - - o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type); - - var tag_offset: u64 = undefined; - var payload_offset: u64 = undefined; - if (layout.tag_align.compare(.gte, layout.payload_align)) { - tag_offset = 0; - payload_offset = layout.payload_align.forward(layout.tag_size); - } else { - payload_offset = 0; - tag_offset = layout.tag_align.forward(layout.payload_size); - } - - const debug_tag_type = try o.builder.debugMemberType( - try o.builder.metadataString("tag"), - file, // File - fwd_ref, - 0, // Line - try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty), required_by_runtime), - layout.tag_size * 8, - (layout.tag_align.toByteUnits() orelse 0) * 8, - tag_offset * 8, - ); - - const debug_payload_type = try o.builder.debugMemberType( - try o.builder.metadataString("payload"), - file, - fwd_ref, - 0, // Line - debug_union_type, - layout.payload_size * 8, - (layout.payload_align.toByteUnits() orelse 0) * 8, - payload_offset * 8, - ); - - const full_fields: [2]Builder.Metadata = - if (layout.tag_align.compare(.gte, layout.payload_align)) - .{ debug_tag_type, debug_payload_type } - else - .{ debug_payload_type, debug_tag_type }; - - const debug_tagged_union_type = try o.builder.debugStructType( - try o.builder.metadataString(name), - file, // File - scope, - line, - .none, // Underlying type - ty.abiSize(pt) * 8, - (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, - try o.builder.debugTuple(&full_fields), - isByRef(ty, pt), - ); - - break :res debug_tagged_union_type; - }, - else => unreachable, // Handled above. - }; - - o.builder.debugForwardReferenceSetType(fwd_ref, res); } } @@ -2811,10 +2779,14 @@ pub const Object = struct { const file_scope = namespace.fileScope(zcu); if (namespace.parent == .none) return try o.getDebugFile(file_scope); - return o.lowerDebugType(zcu.declPtr(namespace.decl_index).val.toType(), false); + const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index); + + if (!gop.found_existing) gop.value_ptr.* = try o.builder.debugForwardReference(); + + return gop.value_ptr.*; } - fn makeNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex, fields: []const Builder.Metadata) !Builder.Metadata { + fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata { const zcu = o.pt.zcu; const decl = zcu.declPtr(decl_index); const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); @@ -2826,8 +2798,7 @@ pub const Object = struct { .none, 0, 0, - if (fields.len == 0) .none else try o.builder.debugTuple(fields), - false, // is_byref + .none, ); } @@ -4741,33 +4712,16 @@ pub const DeclGen = struct { if (!owner_mod.strip) { const debug_file = try o.getDebugFile(file_scope); - const linkage_name = try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)); - const is_internal_linkage = !decl.isExtern(zcu); - - const ty = try o.lowerDebugType(decl.typeOf(zcu), true); const debug_global_var = try o.builder.debugGlobalVar( - linkage_name, - linkage_name, - debug_file, - debug_file, + try o.builder.metadataString(decl.name.toSlice(ip)), // Name + try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name + debug_file, // File + debug_file, // Scope line_number, - ty, + try o.lowerDebugType(decl.typeOf(zcu)), variable_index, - is_internal_linkage, + .{ .local = !decl.isExtern(zcu) }, ); - if (is_internal_linkage) { - const name = try o.builder.metadataString(decl.name.toSlice(ip)); - const debug_scope = try o.namespaceToDebugScope(decl.src_namespace); - - const import = try o.builder.debugImportDeclaration( - name, - debug_file, - debug_scope, - line_number, - debug_global_var, - ); - try o.debug_imports.append(o.gpa, import); - } const debug_expression = try o.builder.debugExpression(&.{}); @@ -5218,12 +5172,11 @@ pub const FuncGen = struct { self.scope = try o.builder.debugSubprogram( self.file, - self.file, // TODO Get the correct scope into here—self.scope is the function's *inner* scope. try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)), try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)), line_number, line_number + func.lbrace_line, - try o.lowerDebugType(fn_ty, true), + try o.lowerDebugType(fn_ty), .{ .di_flags = .{ .StaticMember = true }, .sp_flags = .{ @@ -6773,7 +6726,7 @@ pub const FuncGen = struct { self.file, self.scope, self.prev_dbg_line, - try o.lowerDebugType(ptr_ty.childType(mod), true), + try o.lowerDebugType(ptr_ty.childType(mod)), ); _ = try self.wip.callIntrinsic( @@ -6806,7 +6759,7 @@ pub const FuncGen = struct { self.file, self.scope, self.prev_dbg_line, - try o.lowerDebugType(operand_ty, true), + try o.lowerDebugType(operand_ty), ); const pt = o.pt; @@ -8920,7 +8873,7 @@ pub const FuncGen = struct { self.file, self.scope, lbrace_line, - try o.lowerDebugType(inst_ty, true), + try o.lowerDebugType(inst_ty), @intCast(self.arg_index), ); diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index 7fc0fbdfc0..a23bc86c57 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -7651,8 +7651,6 @@ pub const Metadata = enum(u32) { composite_vector_type, derived_pointer_type, derived_member_type, - derived_typedef, - imported_declaration, subroutine_type, enumerator_unsigned, enumerator_signed_positive, @@ -7698,8 +7696,6 @@ pub const Metadata = enum(u32) { .composite_vector_type, .derived_pointer_type, .derived_member_type, - .derived_typedef, - .imported_declaration, .subroutine_type, .enumerator_unsigned, .enumerator_signed_positive, @@ -7816,7 +7812,6 @@ pub const Metadata = enum(u32) { producer: MetadataString, enums: Metadata, globals: Metadata, - imports: Metadata, }; pub const Subprogram = struct { @@ -7865,7 +7860,6 @@ pub const Metadata = enum(u32) { } }; - scope: Metadata, file: Metadata, name: MetadataString, linkage_name: MetadataString, @@ -7911,10 +7905,6 @@ pub const Metadata = enum(u32) { align_in_bits_lo: u32, align_in_bits_hi: u32, fields_tuple: Metadata, - flags: packed struct(u32) { - is_byref: bool, - pad: u31 = 0, - }, pub fn bitSize(self: CompositeType) u64 { return @as(u64, self.size_in_bits_hi) << 32 | self.size_in_bits_lo; @@ -7948,14 +7938,6 @@ pub const Metadata = enum(u32) { } }; - pub const ImportedEntity = struct { - name: MetadataString, - file: Metadata, - scope: Metadata, - line: u32, - entity: Metadata, - }; - pub const SubroutineType = struct { types_tuple: Metadata, }; @@ -8008,6 +7990,10 @@ pub const Metadata = enum(u32) { }; pub const GlobalVar = struct { + pub const Options = struct { + local: bool, + }; + name: MetadataString, linkage_name: MetadataString, file: Metadata, @@ -8238,7 +8224,6 @@ pub const Metadata = enum(u32) { DIBasicType, DICompositeType, DIDerivedType, - DIImportedEntity, DISubroutineType, DIEnumerator, DISubrange, @@ -9976,7 +9961,7 @@ pub fn printUnbuffered( .enums = extra.enums, .retainedTypes = null, .globals = extra.globals, - .imports = extra.imports, + .imports = null, .macros = null, .dwoId = null, .splitDebugInlining = false, @@ -10000,7 +9985,7 @@ pub fn printUnbuffered( try metadata_formatter.specialized(.@"distinct !", .DISubprogram, .{ .name = extra.name, .linkageName = extra.linkage_name, - .scope = extra.scope, + .scope = extra.file, .file = extra.file, .line = extra.line, .type = extra.ty, @@ -10094,8 +10079,8 @@ pub fn printUnbuffered( else => extra.name, }, .scope = extra.scope, - .file = extra.file, - .line = extra.line, + .file = null, + .line = null, .baseType = extra.underlying_type, .size = extra.bitSize(), .@"align" = extra.bitAlign(), @@ -10116,18 +10101,15 @@ pub fn printUnbuffered( }, .derived_pointer_type, .derived_member_type, - .derived_typedef, => |kind| { const extra = self.metadataExtraData(Metadata.DerivedType, metadata_item.data); try metadata_formatter.specialized(.@"!", .DIDerivedType, .{ .tag = @as(enum { DW_TAG_pointer_type, DW_TAG_member, - DW_TAG_typedef, }, switch (kind) { .derived_pointer_type => .DW_TAG_pointer_type, .derived_member_type => .DW_TAG_member, - .derived_typedef => .DW_TAG_typedef, else => unreachable, }), .name = switch (extra.name) { @@ -10150,22 +10132,6 @@ pub fn printUnbuffered( .annotations = null, }, writer); }, - .imported_declaration => { - const extra = self.metadataExtraData(Metadata.ImportedEntity, metadata_item.data); - - try metadata_formatter.specialized(.@"!", .DIImportedEntity, .{ - .tag = .DW_TAG_imported_declaration, - .scope = extra.scope, - .entity = extra.entity, - .file = extra.file, - .line = extra.line, - .name = switch (extra.name) { - .none => null, - else => extra.name, - }, - .elements = null, - }, writer); - }, .subroutine_type => { const extra = self.metadataExtraData(Metadata.SubroutineType, metadata_item.data); try metadata_formatter.specialized(.@"!", .DISubroutineType, .{ @@ -10289,7 +10255,11 @@ pub fn printUnbuffered( .file = extra.file, .line = extra.line, .type = extra.ty, - .isLocal = kind != .global_var, + .isLocal = switch (kind) { + .global_var => false, + .@"global_var local" => true, + else => unreachable, + }, .isDefinition = true, .declaration = null, .templateParams = null, @@ -11642,17 +11612,7 @@ fn addMetadataExtraAssumeCapacity(self: *Builder, extra: anytype) Metadata.Item. u32 => value, MetadataString, Metadata, Variable.Index, Value => @intFromEnum(value), Metadata.DIFlags => @bitCast(value), - else => blk: { - switch (@typeInfo(field.type)) { - .Struct => |s| { - if (s.backing_integer == u32) - break :blk @bitCast(value); - @compileLog(s.layout, s.backing_integer); - }, - else => {}, - } - @compileError("bad field type: " ++ @typeName(field.type)); - }, + else => @compileError("bad field type: " ++ @typeName(field.type)), }); } return result; @@ -11691,7 +11651,7 @@ fn metadataExtraDataTrail( u32 => value, MetadataString, Metadata, Variable.Index, Value => @enumFromInt(value), Metadata.DIFlags => @bitCast(value), - else => @bitCast(value), + else => @compileError("bad field type: " ++ @typeName(field.type)), }; return .{ .data = result, @@ -11780,17 +11740,15 @@ pub fn debugCompileUnit( producer: MetadataString, enums: Metadata, globals: Metadata, - imports: Metadata, options: Metadata.CompileUnit.Options, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompileUnit, 0); - return self.debugCompileUnitAssumeCapacity(file, producer, enums, globals, imports, options); + return self.debugCompileUnitAssumeCapacity(file, producer, enums, globals, options); } pub fn debugSubprogram( self: *Builder, file: Metadata, - scope: Metadata, name: MetadataString, linkage_name: MetadataString, line: u32, @@ -11802,7 +11760,6 @@ pub fn debugSubprogram( try self.ensureUnusedMetadataCapacity(1, Metadata.Subprogram, 0); return self.debugSubprogramAssumeCapacity( file, - scope, name, linkage_name, line, @@ -11858,7 +11815,6 @@ pub fn debugStructType( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, - is_byref: bool, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugStructTypeAssumeCapacity( @@ -11870,7 +11826,6 @@ pub fn debugStructType( size_in_bits, align_in_bits, fields_tuple, - is_byref, ); } @@ -11884,7 +11839,6 @@ pub fn debugUnionType( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, - is_byref: bool, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugUnionTypeAssumeCapacity( @@ -11896,7 +11850,6 @@ pub fn debugUnionType( size_in_bits, align_in_bits, fields_tuple, - is_byref, ); } @@ -12020,53 +11973,6 @@ pub fn debugMemberType( ); } -pub fn debugTypedef( - self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, - line: u32, - underlying_type: Metadata, - align_in_bits: u64, -) Allocator.Error!Metadata { - try self.ensureUnusedMetadataCapacity(1, Metadata.DerivedType, 0); - - assert(!self.strip); - return self.metadataSimpleAssumeCapacity(.derived_typedef, Metadata.DerivedType{ - .name = name, - .file = file, - .scope = scope, - .line = line, - .underlying_type = underlying_type, - .size_in_bits_lo = 0, - .size_in_bits_hi = 0, - .align_in_bits_lo = @truncate(align_in_bits), - .align_in_bits_hi = @truncate(align_in_bits >> 32), - .offset_in_bits_lo = 0, - .offset_in_bits_hi = 0, - }); -} - -pub fn debugImportDeclaration( - self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, - line: u32, - entity: Metadata, -) Allocator.Error!Metadata { - try self.ensureUnusedMetadataCapacity(1, Metadata.ImportedEntity, 0); - - assert(!self.strip); - return self.metadataSimpleAssumeCapacity(.imported_declaration, Metadata.ImportedEntity{ - .name = name, - .file = file, - .scope = scope, - .line = line, - .entity = entity, - }); -} - pub fn debugSubroutineType( self: *Builder, types_tuple: Metadata, @@ -12157,7 +12063,7 @@ pub fn debugGlobalVar( line: u32, ty: Metadata, variable: Variable.Index, - internal: bool, + options: Metadata.GlobalVar.Options, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.GlobalVar, 0); return self.debugGlobalVarAssumeCapacity( @@ -12168,7 +12074,7 @@ pub fn debugGlobalVar( line, ty, variable, - internal, + options, ); } @@ -12301,7 +12207,6 @@ pub fn debugCompileUnitAssumeCapacity( producer: MetadataString, enums: Metadata, globals: Metadata, - imports: Metadata, options: Metadata.CompileUnit.Options, ) Metadata { assert(!self.strip); @@ -12312,7 +12217,6 @@ pub fn debugCompileUnitAssumeCapacity( .producer = producer, .enums = enums, .globals = globals, - .imports = imports, }, ); } @@ -12320,7 +12224,6 @@ pub fn debugCompileUnitAssumeCapacity( fn debugSubprogramAssumeCapacity( self: *Builder, file: Metadata, - scope: Metadata, name: MetadataString, linkage_name: MetadataString, line: u32, @@ -12334,7 +12237,6 @@ fn debugSubprogramAssumeCapacity( @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2))); return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{ .file = file, - .scope = scope, .name = name, .linkage_name = linkage_name, .line = line, @@ -12418,7 +12320,6 @@ fn debugStructTypeAssumeCapacity( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, - is_byref: bool, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12431,7 +12332,6 @@ fn debugStructTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, - is_byref, ); } @@ -12445,7 +12345,6 @@ fn debugUnionTypeAssumeCapacity( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, - is_byref: bool, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12458,7 +12357,6 @@ fn debugUnionTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, - is_byref, ); } @@ -12484,7 +12382,6 @@ fn debugEnumerationTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, - false, // is_byref ); } @@ -12510,7 +12407,6 @@ fn debugArrayTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, - size_in_bits > 0, // is_byref ); } @@ -12536,7 +12432,6 @@ fn debugVectorTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, - false, ); } @@ -12551,7 +12446,6 @@ fn debugCompositeTypeAssumeCapacity( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, - is_byref: bool, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(tag, Metadata.CompositeType{ @@ -12565,7 +12459,6 @@ fn debugCompositeTypeAssumeCapacity( .align_in_bits_lo = @truncate(align_in_bits), .align_in_bits_hi = @truncate(align_in_bits >> 32), .fields_tuple = fields_tuple, - .flags = .{ .is_byref = is_byref }, }); } @@ -12876,11 +12769,11 @@ fn debugGlobalVarAssumeCapacity( line: u32, ty: Metadata, variable: Variable.Index, - internal: bool, + options: Metadata.GlobalVar.Options, ) Metadata { assert(!self.strip); return self.metadataDistinctAssumeCapacity( - if (internal) .@"global_var local" else .global_var, + if (options.local) .@"global_var local" else .global_var, Metadata.GlobalVar{ .name = name, .linkage_name = linkage_name, @@ -13911,7 +13804,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }, .enums = extra.enums, .globals = extra.globals, - .imports = extra.imports, }, metadata_adapter); }, .subprogram, @@ -13926,7 +13818,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co const extra = self.metadataExtraData(Metadata.Subprogram, data); try metadata_block.writeAbbrevAdapted(MetadataBlock.Subprogram{ - .scope = extra.scope, + .scope = extra.file, .name = extra.name, .linkage_name = extra.linkage_name, .file = extra.file, @@ -14000,24 +13892,18 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .underlying_type = extra.underlying_type, .size_in_bits = extra.bitSize(), .align_in_bits = extra.bitAlign(), - .flags = .{ - .Vector = kind == .composite_vector_type, - .EnumClass = kind == .composite_enumeration_type, - .TypePassbyReference = extra.flags.is_byref, - }, + .flags = if (kind == .composite_vector_type) .{ .Vector = true } else .{}, .elements = extra.fields_tuple, }, metadata_adapter); }, .derived_pointer_type, .derived_member_type, - .derived_typedef, => |kind| { const extra = self.metadataExtraData(Metadata.DerivedType, data); try metadata_block.writeAbbrevAdapted(MetadataBlock.DerivedType{ .tag = switch (kind) { .derived_pointer_type => DW.TAG.pointer_type, .derived_member_type => DW.TAG.member, - .derived_typedef => DW.TAG.typedef, else => unreachable, }, .name = extra.name, @@ -14028,20 +13914,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .size_in_bits = extra.bitSize(), .align_in_bits = extra.bitAlign(), .offset_in_bits = extra.bitOffset(), - .flags = .{ - .StaticMember = false, - }, - }, metadata_adapter); - }, - .imported_declaration => { - const extra = self.metadataExtraData(Metadata.ImportedEntity, data); - try metadata_block.writeAbbrevAdapted(MetadataBlock.ImportedEntity{ - .tag = DW.TAG.imported_declaration, - .scope = extra.scope, - .entity = extra.entity, - .line = extra.line, - .name = extra.name, - .file = extra.file, }, metadata_adapter); }, .subroutine_type => { diff --git a/src/codegen/llvm/ir.zig b/src/codegen/llvm/ir.zig index 2373e626c3..6a7c6c6857 100644 --- a/src/codegen/llvm/ir.zig +++ b/src/codegen/llvm/ir.zig @@ -649,7 +649,6 @@ pub const MetadataBlock = struct { BasicType, CompositeType, DerivedType, - ImportedEntity, SubroutineType, Enumerator, Subrange, @@ -695,7 +694,7 @@ pub const MetadataBlock = struct { pub const ops = [_]AbbrevOp{ .{ .literal = 20 }, .{ .literal = 1 }, // is distinct - .{ .literal = std.dwarf.LANG.C_plus_plus_11 }, // source language + .{ .literal = std.dwarf.LANG.C99 }, // source language MetadataAbbrev, // file MetadataAbbrev, // producer .{ .fixed = 1 }, // isOptimized @@ -707,7 +706,7 @@ pub const MetadataBlock = struct { .{ .literal = 0 }, // retained types .{ .literal = 0 }, // subprograms MetadataAbbrev, // globals - MetadataAbbrev, // imported entities + .{ .literal = 0 }, // imported entities .{ .literal = 0 }, // DWO ID .{ .literal = 0 }, // macros .{ .literal = 0 }, // split debug inlining @@ -723,7 +722,6 @@ pub const MetadataBlock = struct { is_optimized: bool, enums: Builder.Metadata, globals: Builder.Metadata, - imports: Builder.Metadata, }; pub const Subprogram = struct { @@ -865,7 +863,7 @@ pub const MetadataBlock = struct { .{ .vbr = 6 }, // size in bits .{ .vbr = 6 }, // align in bits .{ .vbr = 6 }, // offset in bits - .{ .fixed = 32 }, // flags + .{ .literal = 0 }, // flags .{ .literal = 0 }, // extra data }; @@ -878,28 +876,6 @@ pub const MetadataBlock = struct { size_in_bits: u64, align_in_bits: u64, offset_in_bits: u64, - flags: Builder.Metadata.DIFlags, - }; - - pub const ImportedEntity = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 31 }, - .{ .literal = 0 }, // is distinct - .{ .fixed = 32 }, // tag - MetadataAbbrev, // scope - MetadataAbbrev, // entity - LineAbbrev, // line - MetadataAbbrev, // name - MetadataAbbrev, // file - .{ .literal = 0 }, // elements - }; - - tag: u32, - scope: Builder.Metadata, - entity: Builder.Metadata, - line: u32, - name: Builder.MetadataString, - file: Builder.Metadata, }; pub const SubroutineType = struct { diff --git a/test/cases/llvm/debug_types.zig b/test/cases/llvm/debug_types.zig deleted file mode 100644 index 27bd1b3c61..0000000000 --- a/test/cases/llvm/debug_types.zig +++ /dev/null @@ -1,23 +0,0 @@ -const Ty = struct { - pub const A = void; - pub const B = @Vector(2, u0); - pub const C = u0; - pub const D = enum (u0) {}; - pub const E = type; - pub const F = 1; - pub const G = 1.0; - pub const H = undefined; - pub const I = null; - pub const J = .foo; -}; -pub fn main() void { - inline for (@typeInfo(Ty).Struct.decls) |d|{ - _ = @field(Ty, d.name); - } -} - -// compile -// output_mode=Exe -// backend=llvm -// target=x86_64-linux,x86_64-macos -// \ No newline at end of file