Commit 359bbdd574
Changed files (3)
src
codegen
src/codegen/llvm/Builder.zig
@@ -7652,6 +7652,8 @@ pub const Metadata = enum(u32) {
derived_pointer_type,
derived_member_type,
derived_static_member_type,
+ derived_typedef,
+ imported_declaration,
subroutine_type,
enumerator_unsigned,
enumerator_signed_positive,
@@ -7699,6 +7701,8 @@ pub const Metadata = enum(u32) {
.derived_pointer_type,
.derived_member_type,
.derived_static_member_type,
+ .derived_typedef,
+ .imported_declaration,
.subroutine_type,
.enumerator_unsigned,
.enumerator_signed_positive,
@@ -7816,6 +7820,7 @@ pub const Metadata = enum(u32) {
producer: MetadataString,
enums: Metadata,
globals: Metadata,
+ imports: Metadata,
};
pub const Subprogram = struct {
@@ -7943,6 +7948,14 @@ 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,
};
@@ -8232,6 +8245,7 @@ pub const Metadata = enum(u32) {
DIBasicType,
DICompositeType,
DIDerivedType,
+ DIImportedEntity,
DISubroutineType,
DIEnumerator,
DISubrange,
@@ -9969,7 +9983,7 @@ pub fn printUnbuffered(
.enums = extra.enums,
.retainedTypes = null,
.globals = extra.globals,
- .imports = null,
+ .imports = extra.imports,
.macros = null,
.dwoId = null,
.splitDebugInlining = false,
@@ -10110,16 +10124,18 @@ pub fn printUnbuffered(
.derived_pointer_type,
.derived_member_type,
.derived_static_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,
- .derived_static_member_type => .DW_TAG_member,
+ .derived_member_type, .derived_static_member_type => .DW_TAG_member,
+ .derived_typedef => .DW_TAG_typedef,
else => unreachable,
}),
.name = switch (extra.name) {
@@ -10142,6 +10158,22 @@ 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, .{
@@ -11747,10 +11779,11 @@ 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, options);
+ return self.debugCompileUnitAssumeCapacity(file, producer, enums, globals, imports, options);
}
pub fn debugSubprogram(
@@ -12005,6 +12038,53 @@ 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,
@@ -12241,6 +12321,7 @@ pub fn debugCompileUnitAssumeCapacity(
producer: MetadataString,
enums: Metadata,
globals: Metadata,
+ imports: Metadata,
options: Metadata.CompileUnit.Options,
) Metadata {
assert(!self.strip);
@@ -12251,6 +12332,7 @@ pub fn debugCompileUnitAssumeCapacity(
.producer = producer,
.enums = enums,
.globals = globals,
+ .imports = imports,
},
);
}
@@ -12538,22 +12620,19 @@ fn debugMemberTypeAssumeCapacity(
static: bool,
) Metadata {
assert(!self.strip);
- return self.metadataSimpleAssumeCapacity(
- if (static) .derived_static_member_type else .derived_member_type,
- Metadata.DerivedType{
- .name = name,
- .file = file,
- .scope = scope,
- .line = line,
- .underlying_type = underlying_type,
- .size_in_bits_lo = @truncate(size_in_bits),
- .size_in_bits_hi = @truncate(size_in_bits >> 32),
- .align_in_bits_lo = @truncate(align_in_bits),
- .align_in_bits_hi = @truncate(align_in_bits >> 32),
- .offset_in_bits_lo = @truncate(offset_in_bits),
- .offset_in_bits_hi = @truncate(offset_in_bits >> 32),
- }
- );
+ return self.metadataSimpleAssumeCapacity(if (static) .derived_static_member_type else .derived_member_type, Metadata.DerivedType{
+ .name = name,
+ .file = file,
+ .scope = scope,
+ .line = line,
+ .underlying_type = underlying_type,
+ .size_in_bits_lo = @truncate(size_in_bits),
+ .size_in_bits_hi = @truncate(size_in_bits >> 32),
+ .align_in_bits_lo = @truncate(align_in_bits),
+ .align_in_bits_hi = @truncate(align_in_bits >> 32),
+ .offset_in_bits_lo = @truncate(offset_in_bits),
+ .offset_in_bits_hi = @truncate(offset_in_bits >> 32),
+ });
}
fn debugSubroutineTypeAssumeCapacity(
@@ -13850,6 +13929,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
},
.enums = extra.enums,
.globals = extra.globals,
+ .imports = extra.imports,
}, metadata_adapter);
},
.subprogram,
@@ -13945,13 +14025,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
.derived_pointer_type,
.derived_member_type,
.derived_static_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,
- .derived_static_member_type => DW.TAG.member,
+ .derived_member_type, .derived_static_member_type => DW.TAG.member,
+ .derived_typedef => DW.TAG.typedef,
else => unreachable,
},
.name = extra.name,
@@ -13967,6 +14048,17 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
},
}, 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 => {
const extra = self.metadataExtraData(Metadata.SubroutineType, data);
src/codegen/llvm/ir.zig
@@ -649,6 +649,7 @@ pub const MetadataBlock = struct {
BasicType,
CompositeType,
DerivedType,
+ ImportedEntity,
SubroutineType,
Enumerator,
Subrange,
@@ -706,7 +707,7 @@ pub const MetadataBlock = struct {
.{ .literal = 0 }, // retained types
.{ .literal = 0 }, // subprograms
MetadataAbbrev, // globals
- .{ .literal = 0 }, // imported entities
+ MetadataAbbrev, // imported entities
.{ .literal = 0 }, // DWO ID
.{ .literal = 0 }, // macros
.{ .literal = 0 }, // split debug inlining
@@ -722,6 +723,7 @@ pub const MetadataBlock = struct {
is_optimized: bool,
enums: Builder.Metadata,
globals: Builder.Metadata,
+ imports: Builder.Metadata,
};
pub const Subprogram = struct {
@@ -879,6 +881,27 @@ pub const MetadataBlock = struct {
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 {
pub const ops = [_]AbbrevOp{
.{ .literal = 19 },
src/codegen/llvm.zig
@@ -814,14 +814,17 @@ 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),
- debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),
+ // The value says whether this namespace's type is runtime-required.
+ debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(Type, bool),
target: std.Target,
/// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,
@@ -884,7 +887,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_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref, const debug_imports_fwd_ref =
if (!builder.strip)
debug_info: {
// We fully resolve all paths at this point to avoid lack of
@@ -916,6 +919,7 @@ 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,
@@ -928,6 +932,7 @@ pub const Object = struct {
}),
debug_enums_fwd_ref,
debug_globals_fwd_ref,
+ debug_imports_fwd_ref,
.{ .optimized = comp.root_mod.optimize_mode != .Debug },
);
@@ -983,8 +988,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 };
- } else .{.none} ** 3;
+ break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref, debug_imports_fwd_ref };
+ } else .{.none} ** 4;
const obj = try arena.create(Object);
obj.* = .{
@@ -997,8 +1002,10 @@ 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 = .{},
@@ -1151,6 +1158,11 @@ 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),
+ );
}
}
@@ -1634,7 +1646,7 @@ pub const Object = struct {
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));
+ const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu), true);
const subprogram = try o.builder.debugSubprogram(
file,
@@ -1904,6 +1916,7 @@ pub const Object = struct {
pub fn lowerDebugType(
o: *Object,
ty: Type,
+ required_by_runtime: bool,
) Allocator.Error!Builder.Metadata {
assert(!o.builder.strip);
@@ -1913,8 +1926,13 @@ pub const Object = struct {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
- if (o.debug_type_map.get(ty)) |debug_type| return debug_type;
-
+ 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;
+ }
switch (ty.zigTypeTag(zcu)) {
.Void,
@@ -1988,7 +2006,7 @@ pub const Object = struct {
},
},
});
- const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty);
+ const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty, required_by_runtime);
try o.debug_type_map.put(gpa, ty, debug_ptr_type);
return debug_ptr_type;
}
@@ -2019,7 +2037,7 @@ pub const Object = struct {
.none, // File
debug_fwd_ref,
0, // Line
- try o.lowerDebugType(ptr_ty),
+ try o.lowerDebugType(ptr_ty, required_by_runtime),
ptr_size * 8,
(ptr_align.toByteUnits() orelse 0) * 8,
0, // Offset
@@ -2030,7 +2048,7 @@ pub const Object = struct {
.none, // File
debug_fwd_ref,
0, // Line
- try o.lowerDebugType(len_ty),
+ try o.lowerDebugType(len_ty, required_by_runtime),
len_size * 8,
(len_align.toByteUnits() orelse 0) * 8,
len_offset * 8,
@@ -2059,7 +2077,7 @@ pub const Object = struct {
return debug_slice_type;
}
- const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child));
+ const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child), required_by_runtime);
const name = try o.allocTypeName(ty);
defer gpa.free(name);
@@ -2089,7 +2107,7 @@ pub const Object = struct {
.none, // File
.none, // Scope
0, // Line
- try o.lowerDebugType(ty.childType(zcu)),
+ try o.lowerDebugType(ty.childType(zcu), required_by_runtime),
ty.abiSize(pt) * 8,
(ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
try o.builder.debugTuple(&.{
@@ -2124,7 +2142,7 @@ pub const Object = struct {
try o.builder.metadataString("bool"),
1,
),
- else => try o.lowerDebugType(ty.childType(zcu)),
+ else => try o.lowerDebugType(ty.childType(zcu), required_by_runtime),
};
const debug_vector_type = try o.builder.debugVectorType(
@@ -2166,7 +2184,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);
+ const debug_optional_type = try o.lowerDebugType(child_ty, required_by_runtime);
o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type);
@@ -2189,7 +2207,7 @@ pub const Object = struct {
.none, // File
debug_fwd_ref,
0, // Line
- try o.lowerDebugType(child_ty),
+ try o.lowerDebugType(child_ty, required_by_runtime),
payload_size * 8,
(payload_align.toByteUnits() orelse 0) * 8,
0, // Offset
@@ -2200,7 +2218,7 @@ pub const Object = struct {
.none,
debug_fwd_ref,
0,
- try o.lowerDebugType(non_null_ty),
+ try o.lowerDebugType(non_null_ty, required_by_runtime),
non_null_size * 8,
(non_null_align.toByteUnits() orelse 0) * 8,
non_null_offset * 8,
@@ -2232,7 +2250,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);
+ const debug_error_union_type = try o.lowerDebugType(Type.anyerror, required_by_runtime);
try o.debug_type_map.put(gpa, ty, debug_error_union_type);
return debug_error_union_type;
}
@@ -2269,7 +2287,7 @@ pub const Object = struct {
.none, // File
debug_fwd_ref,
0, // Line
- try o.lowerDebugType(Type.anyerror),
+ try o.lowerDebugType(Type.anyerror, required_by_runtime),
error_size * 8,
(error_align.toByteUnits() orelse 0) * 8,
error_offset * 8,
@@ -2279,7 +2297,7 @@ pub const Object = struct {
.none, // File
debug_fwd_ref,
0, // Line
- try o.lowerDebugType(payload_ty),
+ try o.lowerDebugType(payload_ty, required_by_runtime),
payload_size * 8,
(payload_align.toByteUnits() orelse 0) * 8,
payload_offset * 8,
@@ -2321,21 +2339,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));
+ debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty, required_by_runtime));
if (sret) {
const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type));
- debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
+ debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
}
} else {
- debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void));
+ debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void, required_by_runtime));
}
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));
+ debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
}
for (0..fn_info.param_types.len) |i| {
@@ -2344,9 +2362,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));
+ debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty, required_by_runtime));
} else {
- debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty));
+ debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty, required_by_runtime));
}
}
@@ -2367,421 +2385,419 @@ 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 => {}
+ .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;
+ }
- const owner_decl_index = ty.getOwnerDeclOrNull(zcu);
- const owner_decl: ?*Zcu.Decl =
- if (owner_decl_index) |owner| zcu.declPtr(owner) else null;
+ fn genNamespaces(o: *Object) !void {
+ const gpa = o.gpa;
+ const pt = o.pt;
+ const zcu = pt.zcu;
+ const ip = &zcu.intern_pool;
- 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;
+ 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 name = if (owner_decl) |owner| owner.name.toSlice(ip) else try o.allocTypeName(ty);
- defer if (owner_decl == null) gpa.free(name);
+ const owner_decl_index = ty.getOwnerDeclOrNull(zcu);
+ const owner_decl: ?*Zcu.Decl =
+ if (owner_decl_index) |owner| ip.declPtr(owner) else null;
- switch (ty.zigTypeTag(zcu)) {
- .Enum => {
- 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 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 enum_type = ip.loadEnumType(ty.toIntern());
+ const name = if (owner_decl) |owner| owner.name.toSlice(ip) else try o.allocTypeName(ty);
+ defer if (owner_decl == null) gpa.free(name);
- const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
- defer gpa.free(enumerators);
+ const fwd_ref = o.debug_type_map.get(ty).?;
- const int_ty = Type.fromInterned(enum_type.tag_ty);
- const int_info = ty.intInfo(zcu);
- assert(int_info.bits != 0);
+ fields.clearRetainingCapacity();
- 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();
+ 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);
- enumerators[i] = try o.builder.debugEnumerator(
- try o.builder.metadataString(field_name_ip.toSlice(ip)),
- int_info.signedness == .unsigned,
- int_info.bits,
- bigint,
- );
- }
+ for (namespace.decls.keys()) |decl_id| {
+ const decl = ip.declPtr(decl_id);
+ const decl_name = decl.name.toSlice(ip);
- const debug_enum_type = try o.builder.debugEnumerationType(
- try o.builder.metadataString(name),
- file,
- scope,
- line,
- try o.lowerDebugType(int_ty),
- ty.abiSize(pt) * 8,
- (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
- try o.builder.debugTuple(enumerators),
- );
+ if (!decl.has_tv) continue;
+ if (decl.kind != .named) continue;
+ if (decl.analysis != .complete) continue;
- try o.debug_type_map.put(gpa, ty, debug_enum_type);
- try o.debug_enums.append(gpa, debug_enum_type);
- return debug_enum_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 decl_line = decl.typeSrcLine(zcu) + 1;
- 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
- );
- try o.debug_type_map.put(gpa, ty, debug_opaque_type);
- return debug_opaque_type;
- },
- .Struct => {
- 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;
+ 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;
+ }
+
+ 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
+ ));
+ } else if (decl.val.getVariable(zcu)) |v| {
+ fields.appendAssumeCapacity(try o.builder.debugStaticMemberType(
+ try o.builder.metadataString(decl_name),
+ try o.getDebugFile(namespace.fileScope(zcu)),
+ fwd_ref,
+ decl_line,
+ try o.lowerDebugType(Type.fromInterned(v.ty), false),
+ ));
}
}
+ }
- 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),
- file,
- scope,
- 0, // Line
- .none, // Underlying type
- ty.abiSize(pt) * 8,
- (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
- try o.builder.debugTuple(fields.items),
- );
+ if (!required_by_runtime) {
+ const res = try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
+ o.builder.debugForwardReferenceSetType(fwd_ref, res);
+ continue;
+ }
- o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type);
+ const res = switch (ty.zigTypeTag(zcu)) {
+ .Enum => res: {
+ if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
+ break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
+ }
- 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 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 => {},
- }
+ const enum_type = ip.loadEnumType(ty.toIntern());
- if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
- 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 enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
+ defer gpa.free(enumerators);
- const struct_type = zcu.typeToStruct(ty).?;
+ const int_ty = Type.fromInterned(enum_type.tag_ty);
+ const int_info = ty.intInfo(zcu);
+ assert(int_info.bits != 0);
- var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
- defer fields.deinit(gpa);
+ 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();
- try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
+ 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_fwd_ref = try o.builder.debugForwardReference();
+ 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),
+ );
- // 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);
+ 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,
+ );
+ }
- 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 debug_opaque_type = try o.builder.debugStructType(
+ try o.builder.metadataString(name),
+ file,
+ scope,
+ line,
+ .none, // Underlying type
+ 0, // Size
+ 0, // Align
+ .none, // Fields
);
- const field_offset = ty.structFieldOffset(field_index, pt);
+ 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;
+ }
+ }
- const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
- try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
+ 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,
+ ));
+ }
- fields.appendAssumeCapacity(try o.builder.debugMemberType(
- try o.builder.metadataString(field_name.toSlice(ip)),
- 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),
+ file,
+ scope,
+ 0, // Line
+ .none, // Underlying type
+ ty.abiSize(pt) * 8,
+ (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
+ try o.builder.debugTuple(fields.items),
+ );
- 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),
- );
+ break :res debug_struct_type;
+ },
+ else => {},
+ }
- o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type);
+ if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
+ break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
+ }
+ const struct_type = zcu.typeToStruct(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_struct_type;
+ if (!struct_type.haveLayout(ip) or !struct_type.haveFieldTypes(ip)) {
+ break :res try o.makeNamespaceDebugType(owner_decl_index.?, fields.items);
+ }
- return debug_struct_type;
- },
- .Union => {
- 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;
- }
+ try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
- const layout = pt.getUnionLayout(union_type);
+ 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 debug_fwd_ref = try o.builder.debugForwardReference();
+ const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
+ try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
- // 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);
+ 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,
+ ));
+ }
- if (layout.payload_size == 0) {
- const debug_union_type = try o.builder.debugStructType(
+ const debug_struct_type = try o.builder.debugStructType(
try o.builder.metadataString(name),
file,
scope,
- 0, // Line
+ 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))},
- ),
+ try o.builder.debugTuple(fields.items),
);
- // 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();
+ 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 tag_type = union_type.loadTagType(ip);
+ const layout = pt.getUnionLayout(union_type);
- 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;
+ 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)},
+ ),
+ );
- 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)),
- };
+ break :res debug_union_type;
+ }
- 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)),
- field_size * 8,
- (field_align.toByteUnits() orelse 0) * 8,
- 0, // Offset
- ));
- }
+ try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len);
- 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_fwd_ref = if (layout.tag_size == 0)
+ fwd_ref
+ else
+ try o.builder.debugForwardReference();
- 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),
- );
+ const tag_type = union_type.loadTagType(ip);
- o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type);
+ 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;
- 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;
+ 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)),
+ };
- return debug_union_type;
- }
+ 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 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);
- }
+ 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_tag_type = try o.builder.debugMemberType(
- try o.builder.metadataString("tag"),
- file, // 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_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),
+ );
- const debug_payload_type = try o.builder.debugMemberType(
- try o.builder.metadataString("payload"),
- file,
- debug_fwd_ref,
- 0, // Line
- debug_union_type,
- layout.payload_size * 8,
- (layout.payload_align.toByteUnits() orelse 0) * 8,
- payload_offset * 8,
- );
+ if (layout.tag_size == 0) {
+ break :res debug_union_type;
+ }
- 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 };
+ o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_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),
- );
+ 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);
+ }
- o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_tagged_union_type);
+ 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,
+ );
- // 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;
+ 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,
+ );
- return debug_tagged_union_type;
- },
- else => unreachable, // Handled above.
- }
- }
+ 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 };
- fn genNamespaces(o: *Object) !void {
- var i: usize = 0;
- while (i < o.debug_unresolved_namespace_scopes.count()) : (i += 1) {
- const namespace_index = o.debug_unresolved_namespace_scopes.keys()[i];
- const fwd_ref = o.debug_unresolved_namespace_scopes.values()[i];
+ 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),
+ );
- const namespace = o.pt.zcu.namespacePtr(namespace_index);
- const debug_type = try o.lowerDebugType(namespace.getType(o.pt.zcu));
+ break :res debug_tagged_union_type;
+ },
+ else => unreachable, // Handled above.
+ };
- o.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
+ o.builder.debugForwardReferenceSetType(fwd_ref, res);
}
}
@@ -2791,14 +2807,10 @@ pub const Object = struct {
const file_scope = namespace.fileScope(zcu);
if (namespace.parent == .none) return try o.getDebugFile(file_scope);
- 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.*;
+ return o.lowerDebugType(zcu.declPtr(namespace.decl_index).val.toType(), false);
}
- fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata {
+ fn makeNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex, fields: []const Builder.Metadata) !Builder.Metadata {
const zcu = o.pt.zcu;
const decl = zcu.declPtr(decl_index);
const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
@@ -2810,7 +2822,7 @@ pub const Object = struct {
.none,
0,
0,
- .none,
+ if (fields.len == 0) .none else try o.builder.debugTuple(fields),
);
}
@@ -4723,6 +4735,7 @@ pub const DeclGen = struct {
if (!owner_mod.strip) {
const debug_file = try o.getDebugFile(file_scope);
+ const debug_scope = try o.namespaceToDebugScope(decl.src_namespace);
const linkage_name = try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder));
@@ -4730,10 +4743,10 @@ pub const DeclGen = struct {
// Imitate a C++ static member variable since neither
// GDB or LLDB can really cope with regular variables
// directly inside a struct type.
- const ty = try o.lowerDebugType(decl.typeOf(zcu));
+ const ty = try o.lowerDebugType(decl.typeOf(zcu), true);
const name = try o.builder.metadataString(decl.name.toSlice(ip));
- break :blk try o.builder.debugGlobalVar(
+ const variable = try o.builder.debugGlobalVar(
name,
linkage_name,
debug_file,
@@ -4742,15 +4755,25 @@ pub const DeclGen = struct {
ty,
variable_index,
.none,
- .internal,
+ .external,
);
+
+ try o.debug_imports.append(o.gpa, try o.builder.debugImportDeclaration(
+ name,
+ debug_file,
+ debug_scope,
+ line_number,
+ variable,
+ ));
+
+ break :blk variable;
} else try o.builder.debugGlobalVar(
linkage_name,
linkage_name,
debug_file,
debug_file,
line_number,
- try o.lowerDebugType(decl.typeOf(zcu)),
+ try o.lowerDebugType(decl.typeOf(zcu), true),
variable_index,
.none,
.external,
@@ -5209,7 +5232,7 @@ pub const FuncGen = struct {
try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)),
line_number,
line_number + func.lbrace_line,
- try o.lowerDebugType(fn_ty),
+ try o.lowerDebugType(fn_ty, true),
.{
.di_flags = .{ .StaticMember = true },
.sp_flags = .{
@@ -6759,7 +6782,7 @@ pub const FuncGen = struct {
self.file,
self.scope,
self.prev_dbg_line,
- try o.lowerDebugType(ptr_ty.childType(mod)),
+ try o.lowerDebugType(ptr_ty.childType(mod), true),
);
_ = try self.wip.callIntrinsic(
@@ -6792,7 +6815,7 @@ pub const FuncGen = struct {
self.file,
self.scope,
self.prev_dbg_line,
- try o.lowerDebugType(operand_ty),
+ try o.lowerDebugType(operand_ty, true),
);
const pt = o.pt;
@@ -8906,7 +8929,7 @@ pub const FuncGen = struct {
self.file,
self.scope,
lbrace_line,
- try o.lowerDebugType(inst_ty),
+ try o.lowerDebugType(inst_ty, true),
@intCast(self.arg_index),
);