Merge pull request #20424 from mlugg/the-great-decl-split
Dismantle Decl a little bit more
This commit is contained in:
@@ -4368,7 +4368,7 @@ fn fnDecl(
|
||||
decl_inst,
|
||||
std.zig.hashSrc(tree.getNodeSource(decl_node)),
|
||||
.{ .named = fn_name_token },
|
||||
decl_gz.decl_line - gz.decl_line,
|
||||
decl_gz.decl_line,
|
||||
is_pub,
|
||||
is_export,
|
||||
doc_comment_index,
|
||||
@@ -4529,7 +4529,7 @@ fn globalVarDecl(
|
||||
decl_inst,
|
||||
std.zig.hashSrc(tree.getNodeSource(node)),
|
||||
.{ .named = name_token },
|
||||
block_scope.decl_line - gz.decl_line,
|
||||
block_scope.decl_line,
|
||||
is_pub,
|
||||
is_export,
|
||||
doc_comment_index,
|
||||
@@ -4579,7 +4579,7 @@ fn comptimeDecl(
|
||||
decl_inst,
|
||||
std.zig.hashSrc(tree.getNodeSource(node)),
|
||||
.@"comptime",
|
||||
decl_block.decl_line - gz.decl_line,
|
||||
decl_block.decl_line,
|
||||
false,
|
||||
false,
|
||||
.empty,
|
||||
@@ -4629,7 +4629,7 @@ fn usingnamespaceDecl(
|
||||
decl_inst,
|
||||
std.zig.hashSrc(tree.getNodeSource(node)),
|
||||
.@"usingnamespace",
|
||||
decl_block.decl_line - gz.decl_line,
|
||||
decl_block.decl_line,
|
||||
is_pub,
|
||||
false,
|
||||
.empty,
|
||||
@@ -4818,7 +4818,7 @@ fn testDecl(
|
||||
decl_inst,
|
||||
std.zig.hashSrc(tree.getNodeSource(node)),
|
||||
test_name,
|
||||
decl_block.decl_line - gz.decl_line,
|
||||
decl_block.decl_line,
|
||||
false,
|
||||
false,
|
||||
.empty,
|
||||
@@ -13861,7 +13861,7 @@ fn setDeclaration(
|
||||
decl_inst: Zir.Inst.Index,
|
||||
src_hash: std.zig.SrcHash,
|
||||
name: DeclarationName,
|
||||
line_offset: u32,
|
||||
src_line: u32,
|
||||
is_pub: bool,
|
||||
is_export: bool,
|
||||
doc_comment: Zir.NullTerminatedString,
|
||||
@@ -13913,7 +13913,7 @@ fn setDeclaration(
|
||||
.@"comptime" => .@"comptime",
|
||||
.@"usingnamespace" => .@"usingnamespace",
|
||||
},
|
||||
.line_offset = line_offset,
|
||||
.src_line = src_line,
|
||||
.flags = .{
|
||||
.value_body_len = @intCast(value_len),
|
||||
.is_pub = is_pub,
|
||||
|
||||
@@ -2598,9 +2598,7 @@ pub const Inst = struct {
|
||||
src_hash_3: u32,
|
||||
/// The name of this `Decl`. Also indicates whether it is a test, comptime block, etc.
|
||||
name: Name,
|
||||
/// This Decl's line number relative to that of its parent.
|
||||
/// TODO: column must be encoded similarly to respect non-formatted code!
|
||||
line_offset: u32,
|
||||
src_line: u32,
|
||||
flags: Flags,
|
||||
|
||||
pub const Flags = packed struct(u32) {
|
||||
|
||||
@@ -3494,7 +3494,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
|
||||
.{@errorName(err)},
|
||||
));
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.retryable_failures.append(gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
|
||||
try module.retryable_failures.append(gpa, InternPool.AnalSubject.wrap(.{ .decl = decl_index }));
|
||||
};
|
||||
},
|
||||
.analyze_mod => |pkg| {
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace_name_deps: std.AutoArrayHashMapUnmanaged(NamespaceNameKey, DepEntry.In
|
||||
/// Given a `Depender`, points to an entry in `dep_entries` whose `depender`
|
||||
/// matches. The `next_dependee` field can be used to iterate all such entries
|
||||
/// and remove them from the corresponding lists.
|
||||
first_dependency: std.AutoArrayHashMapUnmanaged(Depender, DepEntry.Index) = .{},
|
||||
first_dependency: std.AutoArrayHashMapUnmanaged(AnalSubject, DepEntry.Index) = .{},
|
||||
|
||||
/// Stores dependency information. The hashmaps declared above are used to look
|
||||
/// up entries in this list as required. This is not stored in `extra` so that
|
||||
@@ -132,39 +132,39 @@ pub fn trackZir(ip: *InternPool, gpa: Allocator, file: *Module.File, inst: Zir.I
|
||||
return @enumFromInt(gop.index);
|
||||
}
|
||||
|
||||
/// Reperesents the "source" of a dependency edge, i.e. either a Decl or a
|
||||
/// runtime function (represented as an InternPool index).
|
||||
/// MSB is 0 for a Decl, 1 for a function.
|
||||
pub const Depender = enum(u32) {
|
||||
_,
|
||||
/// Analysis Subject. Represents a single entity which undergoes semantic analysis.
|
||||
/// This is either a `Decl` (in future `Cau`) or a runtime function.
|
||||
/// The LSB is used as a tag bit.
|
||||
/// This is the "source" of an incremental dependency edge.
|
||||
pub const AnalSubject = packed struct(u32) {
|
||||
kind: enum(u1) { decl, func },
|
||||
index: u31,
|
||||
pub const Unwrapped = union(enum) {
|
||||
decl: DeclIndex,
|
||||
func: InternPool.Index,
|
||||
};
|
||||
pub fn unwrap(dep: Depender) Unwrapped {
|
||||
const tag: u1 = @truncate(@intFromEnum(dep) >> 31);
|
||||
const val: u31 = @truncate(@intFromEnum(dep));
|
||||
return switch (tag) {
|
||||
0 => .{ .decl = @enumFromInt(val) },
|
||||
1 => .{ .func = @enumFromInt(val) },
|
||||
pub fn unwrap(as: AnalSubject) Unwrapped {
|
||||
return switch (as.kind) {
|
||||
.decl => .{ .decl = @enumFromInt(as.index) },
|
||||
.func => .{ .func = @enumFromInt(as.index) },
|
||||
};
|
||||
}
|
||||
pub fn wrap(raw: Unwrapped) Depender {
|
||||
return @enumFromInt(switch (raw) {
|
||||
.decl => |decl| @intFromEnum(decl),
|
||||
.func => |func| (1 << 31) | @intFromEnum(func),
|
||||
});
|
||||
pub fn wrap(raw: Unwrapped) AnalSubject {
|
||||
return switch (raw) {
|
||||
.decl => |decl| .{ .kind = .decl, .index = @intCast(@intFromEnum(decl)) },
|
||||
.func => |func| .{ .kind = .func, .index = @intCast(@intFromEnum(func)) },
|
||||
};
|
||||
}
|
||||
pub fn toOptional(dep: Depender) Optional {
|
||||
return @enumFromInt(@intFromEnum(dep));
|
||||
pub fn toOptional(as: AnalSubject) Optional {
|
||||
return @enumFromInt(@as(u32, @bitCast(as)));
|
||||
}
|
||||
pub const Optional = enum(u32) {
|
||||
none = std.math.maxInt(u32),
|
||||
_,
|
||||
pub fn unwrap(opt: Optional) ?Depender {
|
||||
pub fn unwrap(opt: Optional) ?AnalSubject {
|
||||
return switch (opt) {
|
||||
.none => null,
|
||||
_ => @enumFromInt(@intFromEnum(opt)),
|
||||
_ => @bitCast(@intFromEnum(opt)),
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -178,7 +178,7 @@ pub const Dependee = union(enum) {
|
||||
namespace_name: NamespaceNameKey,
|
||||
};
|
||||
|
||||
pub fn removeDependenciesForDepender(ip: *InternPool, gpa: Allocator, depender: Depender) void {
|
||||
pub fn removeDependenciesForDepender(ip: *InternPool, gpa: Allocator, depender: AnalSubject) void {
|
||||
var opt_idx = (ip.first_dependency.fetchSwapRemove(depender) orelse return).value.toOptional();
|
||||
|
||||
while (opt_idx.unwrap()) |idx| {
|
||||
@@ -207,7 +207,7 @@ pub fn removeDependenciesForDepender(ip: *InternPool, gpa: Allocator, depender:
|
||||
pub const DependencyIterator = struct {
|
||||
ip: *const InternPool,
|
||||
next_entry: DepEntry.Index.Optional,
|
||||
pub fn next(it: *DependencyIterator) ?Depender {
|
||||
pub fn next(it: *DependencyIterator) ?AnalSubject {
|
||||
const idx = it.next_entry.unwrap() orelse return null;
|
||||
const entry = it.ip.dep_entries.items[@intFromEnum(idx)];
|
||||
it.next_entry = entry.next;
|
||||
@@ -236,7 +236,7 @@ pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyI
|
||||
};
|
||||
}
|
||||
|
||||
pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: Depender, dependee: Dependee) Allocator.Error!void {
|
||||
pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalSubject, dependee: Dependee) Allocator.Error!void {
|
||||
const first_depender_dep: DepEntry.Index.Optional = if (ip.first_dependency.get(depender)) |idx| dep: {
|
||||
// The entry already exists, so there is capacity to overwrite it later.
|
||||
break :dep idx.toOptional();
|
||||
@@ -300,7 +300,7 @@ pub const DepEntry = extern struct {
|
||||
/// the first and only entry in one of `intern_pool.*_deps`, and does not
|
||||
/// appear in any list by `first_dependency`, but is not in
|
||||
/// `free_dep_entries` since `*_deps` stores a reference to it.
|
||||
depender: Depender.Optional,
|
||||
depender: AnalSubject.Optional,
|
||||
/// Index into `dep_entries` forming a doubly linked list of all dependencies on this dependee.
|
||||
/// Used to iterate all dependers for a given dependee during an update.
|
||||
/// null if this is the end of the list.
|
||||
@@ -6958,7 +6958,6 @@ fn finishFuncInstance(
|
||||
const decl_index = try ip.createDecl(gpa, .{
|
||||
.name = undefined,
|
||||
.src_namespace = fn_owner_decl.src_namespace,
|
||||
.src_line = fn_owner_decl.src_line,
|
||||
.has_tv = true,
|
||||
.owns_tv = true,
|
||||
.val = @import("Value.zig").fromInterned(func_index),
|
||||
|
||||
51
src/Sema.zig
51
src/Sema.zig
@@ -2735,12 +2735,12 @@ fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
|
||||
if (!zcu.comp.debug_incremental) return false;
|
||||
|
||||
const decl_index = Type.fromInterned(ty).getOwnerDecl(zcu);
|
||||
const decl_as_depender = InternPool.Depender.wrap(.{ .decl = decl_index });
|
||||
const decl_as_depender = InternPool.AnalSubject.wrap(.{ .decl = decl_index });
|
||||
const was_outdated = zcu.outdated.swapRemove(decl_as_depender) or
|
||||
zcu.potentially_outdated.swapRemove(decl_as_depender);
|
||||
if (!was_outdated) return false;
|
||||
_ = zcu.outdated_ready.swapRemove(decl_as_depender);
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalSubject.wrap(.{ .decl = decl_index }));
|
||||
zcu.intern_pool.remove(ty);
|
||||
zcu.declPtr(decl_index).analysis = .dependency_failure;
|
||||
try zcu.markDependeeOutdated(.{ .decl_val = decl_index });
|
||||
@@ -2827,7 +2827,6 @@ fn zirStructDecl(
|
||||
small.name_strategy,
|
||||
"struct",
|
||||
inst,
|
||||
extra.data.src_line,
|
||||
);
|
||||
mod.declPtr(new_decl_index).owns_tv = true;
|
||||
errdefer mod.abortAnonDecl(new_decl_index);
|
||||
@@ -2835,7 +2834,7 @@ fn zirStructDecl(
|
||||
if (sema.mod.comp.debug_incremental) {
|
||||
try ip.addDependency(
|
||||
sema.gpa,
|
||||
InternPool.Depender.wrap(.{ .decl = new_decl_index }),
|
||||
InternPool.AnalSubject.wrap(.{ .decl = new_decl_index }),
|
||||
.{ .src_hash = try ip.trackZir(sema.gpa, block.getFileScope(mod), inst) },
|
||||
);
|
||||
}
|
||||
@@ -2864,7 +2863,6 @@ fn createAnonymousDeclTypeNamed(
|
||||
name_strategy: Zir.Inst.NameStrategy,
|
||||
anon_prefix: []const u8,
|
||||
inst: ?Zir.Inst.Index,
|
||||
src_line: u32,
|
||||
) !InternPool.DeclIndex {
|
||||
const zcu = sema.mod;
|
||||
const ip = &zcu.intern_pool;
|
||||
@@ -2876,7 +2874,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
switch (name_strategy) {
|
||||
.anon => {}, // handled after switch
|
||||
.parent => {
|
||||
try zcu.initNewAnonDecl(new_decl_index, src_line, val, block.type_name_ctx);
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, block.type_name_ctx);
|
||||
return new_decl_index;
|
||||
},
|
||||
.func => func_strat: {
|
||||
@@ -2921,7 +2919,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
|
||||
try writer.writeByte(')');
|
||||
const name = try ip.getOrPutString(gpa, buf.items, .no_embedded_nulls);
|
||||
try zcu.initNewAnonDecl(new_decl_index, src_line, val, name);
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
return new_decl_index;
|
||||
},
|
||||
.dbg_var => {
|
||||
@@ -2935,7 +2933,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
const name = try ip.getOrPutStringFmt(gpa, "{}.{s}", .{
|
||||
block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
|
||||
}, .no_embedded_nulls);
|
||||
try zcu.initNewAnonDecl(new_decl_index, src_line, val, name);
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
return new_decl_index;
|
||||
},
|
||||
else => {},
|
||||
@@ -2956,7 +2954,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
|
||||
block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
|
||||
}, .no_embedded_nulls) catch unreachable;
|
||||
try zcu.initNewAnonDecl(new_decl_index, src_line, val, name);
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
return new_decl_index;
|
||||
}
|
||||
|
||||
@@ -3062,7 +3060,6 @@ fn zirEnumDecl(
|
||||
small.name_strategy,
|
||||
"enum",
|
||||
inst,
|
||||
extra.data.src_line,
|
||||
);
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
new_decl.owns_tv = true;
|
||||
@@ -3071,7 +3068,7 @@ fn zirEnumDecl(
|
||||
if (sema.mod.comp.debug_incremental) {
|
||||
try mod.intern_pool.addDependency(
|
||||
sema.gpa,
|
||||
InternPool.Depender.wrap(.{ .decl = new_decl_index }),
|
||||
InternPool.AnalSubject.wrap(.{ .decl = new_decl_index }),
|
||||
.{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
|
||||
);
|
||||
}
|
||||
@@ -3330,7 +3327,6 @@ fn zirUnionDecl(
|
||||
small.name_strategy,
|
||||
"union",
|
||||
inst,
|
||||
extra.data.src_line,
|
||||
);
|
||||
mod.declPtr(new_decl_index).owns_tv = true;
|
||||
errdefer mod.abortAnonDecl(new_decl_index);
|
||||
@@ -3338,7 +3334,7 @@ fn zirUnionDecl(
|
||||
if (sema.mod.comp.debug_incremental) {
|
||||
try mod.intern_pool.addDependency(
|
||||
sema.gpa,
|
||||
InternPool.Depender.wrap(.{ .decl = new_decl_index }),
|
||||
InternPool.AnalSubject.wrap(.{ .decl = new_decl_index }),
|
||||
.{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
|
||||
);
|
||||
}
|
||||
@@ -3419,7 +3415,6 @@ fn zirOpaqueDecl(
|
||||
small.name_strategy,
|
||||
"opaque",
|
||||
inst,
|
||||
extra.data.src_line,
|
||||
);
|
||||
mod.declPtr(new_decl_index).owns_tv = true;
|
||||
errdefer mod.abortAnonDecl(new_decl_index);
|
||||
@@ -3427,7 +3422,7 @@ fn zirOpaqueDecl(
|
||||
if (sema.mod.comp.debug_incremental) {
|
||||
try ip.addDependency(
|
||||
gpa,
|
||||
InternPool.Depender.wrap(.{ .decl = new_decl_index }),
|
||||
InternPool.AnalSubject.wrap(.{ .decl = new_decl_index }),
|
||||
.{ .src_hash = try ip.trackZir(gpa, block.getFileScope(mod), inst) },
|
||||
);
|
||||
}
|
||||
@@ -21546,7 +21541,7 @@ fn zirReify(
|
||||
.needed_comptime_reason = "struct fields must be comptime-known",
|
||||
});
|
||||
|
||||
return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy, is_tuple_val.toBool(), extra.src_line);
|
||||
return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy, is_tuple_val.toBool());
|
||||
},
|
||||
.Enum => {
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
@@ -21575,7 +21570,7 @@ fn zirReify(
|
||||
.needed_comptime_reason = "enum fields must be comptime-known",
|
||||
});
|
||||
|
||||
return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_arr, name_strategy, extra.src_line);
|
||||
return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_arr, name_strategy);
|
||||
},
|
||||
.Opaque => {
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
@@ -21606,7 +21601,6 @@ fn zirReify(
|
||||
name_strategy,
|
||||
"opaque",
|
||||
inst,
|
||||
extra.src_line,
|
||||
);
|
||||
mod.declPtr(new_decl_index).owns_tv = true;
|
||||
errdefer mod.abortAnonDecl(new_decl_index);
|
||||
@@ -21643,7 +21637,7 @@ fn zirReify(
|
||||
.needed_comptime_reason = "union fields must be comptime-known",
|
||||
});
|
||||
|
||||
return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy, extra.src_line);
|
||||
return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy);
|
||||
},
|
||||
.Fn => {
|
||||
const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
|
||||
@@ -21745,7 +21739,6 @@ fn reifyEnum(
|
||||
is_exhaustive: bool,
|
||||
fields_val: Value,
|
||||
name_strategy: Zir.Inst.NameStrategy,
|
||||
src_line: u32,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const mod = sema.mod;
|
||||
const gpa = sema.gpa;
|
||||
@@ -21807,7 +21800,6 @@ fn reifyEnum(
|
||||
name_strategy,
|
||||
"enum",
|
||||
inst,
|
||||
src_line,
|
||||
);
|
||||
mod.declPtr(new_decl_index).owns_tv = true;
|
||||
errdefer mod.abortAnonDecl(new_decl_index);
|
||||
@@ -21871,7 +21863,6 @@ fn reifyUnion(
|
||||
opt_tag_type_val: Value,
|
||||
fields_val: Value,
|
||||
name_strategy: Zir.Inst.NameStrategy,
|
||||
src_line: u32,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const mod = sema.mod;
|
||||
const gpa = sema.gpa;
|
||||
@@ -21955,7 +21946,6 @@ fn reifyUnion(
|
||||
name_strategy,
|
||||
"union",
|
||||
inst,
|
||||
src_line,
|
||||
);
|
||||
mod.declPtr(new_decl_index).owns_tv = true;
|
||||
errdefer mod.abortAnonDecl(new_decl_index);
|
||||
@@ -22051,7 +22041,7 @@ fn reifyUnion(
|
||||
}
|
||||
}
|
||||
|
||||
const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index), src_line);
|
||||
const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));
|
||||
break :tag_ty .{ enum_tag_ty, false };
|
||||
};
|
||||
errdefer if (!has_explicit_tag) ip.remove(enum_tag_ty); // remove generated tag type on error
|
||||
@@ -22112,7 +22102,6 @@ fn reifyStruct(
|
||||
fields_val: Value,
|
||||
name_strategy: Zir.Inst.NameStrategy,
|
||||
is_tuple: bool,
|
||||
src_line: u32,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const mod = sema.mod;
|
||||
const gpa = sema.gpa;
|
||||
@@ -22213,7 +22202,6 @@ fn reifyStruct(
|
||||
name_strategy,
|
||||
"struct",
|
||||
inst,
|
||||
src_line,
|
||||
);
|
||||
mod.declPtr(new_decl_index).owns_tv = true;
|
||||
errdefer mod.abortAnonDecl(new_decl_index);
|
||||
@@ -26347,7 +26335,6 @@ fn zirBuiltinExtern(
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
try mod.initNewAnonDecl(
|
||||
new_decl_index,
|
||||
sema.owner_decl.src_line,
|
||||
Value.fromInterned(
|
||||
if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
|
||||
try ip.getExternFunc(sema.gpa, .{
|
||||
@@ -36745,10 +36732,10 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
|
||||
return sema.failWithOwnedErrorMsg(&block_scope, msg);
|
||||
}
|
||||
} else if (enum_field_vals.count() > 0) {
|
||||
const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), mod.declPtr(union_type.decl), extra.data.src_line);
|
||||
const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), mod.declPtr(union_type.decl));
|
||||
union_type.tagTypePtr(ip).* = enum_ty;
|
||||
} else {
|
||||
const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, mod.declPtr(union_type.decl), extra.data.src_line);
|
||||
const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, mod.declPtr(union_type.decl));
|
||||
union_type.tagTypePtr(ip).* = enum_ty;
|
||||
}
|
||||
}
|
||||
@@ -36766,7 +36753,6 @@ fn generateUnionTagTypeNumbered(
|
||||
enum_field_names: []const InternPool.NullTerminatedString,
|
||||
enum_field_vals: []const InternPool.Index,
|
||||
union_owner_decl: *Module.Decl,
|
||||
src_line: u32,
|
||||
) !InternPool.Index {
|
||||
const mod = sema.mod;
|
||||
const gpa = sema.gpa;
|
||||
@@ -36783,7 +36769,6 @@ fn generateUnionTagTypeNumbered(
|
||||
);
|
||||
try mod.initNewAnonDecl(
|
||||
new_decl_index,
|
||||
src_line,
|
||||
Value.@"unreachable",
|
||||
name,
|
||||
);
|
||||
@@ -36816,7 +36801,6 @@ fn generateUnionTagTypeSimple(
|
||||
block: *Block,
|
||||
enum_field_names: []const InternPool.NullTerminatedString,
|
||||
union_owner_decl: *Module.Decl,
|
||||
src_line: u32,
|
||||
) !InternPool.Index {
|
||||
const mod = sema.mod;
|
||||
const ip = &mod.intern_pool;
|
||||
@@ -36834,7 +36818,6 @@ fn generateUnionTagTypeSimple(
|
||||
);
|
||||
try mod.initNewAnonDecl(
|
||||
new_decl_index,
|
||||
src_line,
|
||||
Value.@"unreachable",
|
||||
name,
|
||||
);
|
||||
@@ -38379,7 +38362,7 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
|
||||
return;
|
||||
}
|
||||
|
||||
const depender = InternPool.Depender.wrap(
|
||||
const depender = InternPool.AnalSubject.wrap(
|
||||
if (sema.owner_func_index != .none)
|
||||
.{ .func = sema.owner_func_index }
|
||||
else
|
||||
|
||||
109
src/Zcu.zig
109
src/Zcu.zig
@@ -139,26 +139,26 @@ global_error_set: GlobalErrorSet = .{},
|
||||
/// Maximum amount of distinct error values, set by --error-limit
|
||||
error_limit: ErrorInt,
|
||||
|
||||
/// Value is the number of PO or outdated Decls which this Depender depends on.
|
||||
potentially_outdated: std.AutoArrayHashMapUnmanaged(InternPool.Depender, u32) = .{},
|
||||
/// Value is the number of PO or outdated Decls which this Depender depends on.
|
||||
/// Once this value drops to 0, the Depender is a candidate for re-analysis.
|
||||
outdated: std.AutoArrayHashMapUnmanaged(InternPool.Depender, u32) = .{},
|
||||
/// This contains all `Depender`s in `outdated` whose PO dependency count is 0.
|
||||
/// Such `Depender`s are ready for immediate re-analysis.
|
||||
/// Value is the number of PO or outdated Decls which this AnalSubject depends on.
|
||||
potentially_outdated: std.AutoArrayHashMapUnmanaged(InternPool.AnalSubject, u32) = .{},
|
||||
/// Value is the number of PO or outdated Decls which this AnalSubject depends on.
|
||||
/// Once this value drops to 0, the AnalSubject is a candidate for re-analysis.
|
||||
outdated: std.AutoArrayHashMapUnmanaged(InternPool.AnalSubject, u32) = .{},
|
||||
/// This contains all `AnalSubject`s in `outdated` whose PO dependency count is 0.
|
||||
/// Such `AnalSubject`s are ready for immediate re-analysis.
|
||||
/// See `findOutdatedToAnalyze` for details.
|
||||
outdated_ready: std.AutoArrayHashMapUnmanaged(InternPool.Depender, void) = .{},
|
||||
outdated_ready: std.AutoArrayHashMapUnmanaged(InternPool.AnalSubject, void) = .{},
|
||||
/// This contains a set of Decls which may not be in `outdated`, but are the
|
||||
/// root Decls of files which have updated source and thus must be re-analyzed.
|
||||
/// If such a Decl is only in this set, the struct type index may be preserved
|
||||
/// (only the namespace might change). If such a Decl is also `outdated`, the
|
||||
/// struct type index must be recreated.
|
||||
outdated_file_root: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
|
||||
/// This contains a list of Dependers whose analysis or codegen failed, but the
|
||||
/// This contains a list of AnalSubject whose analysis or codegen failed, but the
|
||||
/// failure was something like running out of disk space, and trying again may
|
||||
/// succeed. On the next update, we will flush this list, marking all members of
|
||||
/// it as outdated.
|
||||
retryable_failures: std.ArrayListUnmanaged(InternPool.Depender) = .{},
|
||||
retryable_failures: std.ArrayListUnmanaged(InternPool.AnalSubject) = .{},
|
||||
|
||||
stage1_flags: packed struct {
|
||||
have_winmain: bool = false,
|
||||
@@ -347,10 +347,6 @@ pub const Decl = struct {
|
||||
/// there is no parent.
|
||||
src_namespace: Namespace.Index,
|
||||
|
||||
/// Line number corresponding to `src_node`. Stored separately so that source files
|
||||
/// do not need to be loaded into memory in order to compute debug line numbers.
|
||||
/// This value is absolute.
|
||||
src_line: u32,
|
||||
/// Index of the ZIR `declaration` instruction from which this `Decl` was created.
|
||||
/// For the root `Decl` of a `File` and legacy anonymous decls, this is `.none`.
|
||||
zir_decl_index: InternPool.TrackedInst.Index.Optional,
|
||||
@@ -564,6 +560,33 @@ pub const Decl = struct {
|
||||
.offset = LazySrcLoc.Offset.nodeOffset(0),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn navSrcLine(decl: Decl, zcu: *Zcu) u32 {
|
||||
const tracked = decl.zir_decl_index.unwrap() orelse inst: {
|
||||
// generic instantiation
|
||||
assert(decl.has_tv);
|
||||
assert(decl.owns_tv);
|
||||
const generic_owner_func = switch (zcu.intern_pool.indexToKey(decl.val.toIntern())) {
|
||||
.func => |func| func.generic_owner,
|
||||
else => return 0, // TODO: this is probably a `variable` or something; figure this out when we finish sorting out `Decl`.
|
||||
};
|
||||
const generic_owner_decl = zcu.declPtr(zcu.funcInfo(generic_owner_func).owner_decl);
|
||||
break :inst generic_owner_decl.zir_decl_index.unwrap().?;
|
||||
};
|
||||
const info = tracked.resolveFull(&zcu.intern_pool);
|
||||
const file = zcu.import_table.values()[zcu.path_digest_map.getIndex(info.path_digest).?];
|
||||
assert(file.zir_loaded);
|
||||
const zir = file.zir;
|
||||
const inst = zir.instructions.get(@intFromEnum(info.inst));
|
||||
assert(inst.tag == .declaration);
|
||||
return zir.extraData(Zir.Inst.Declaration, inst.data.declaration.payload_index).data.src_line;
|
||||
}
|
||||
|
||||
pub fn typeSrcLine(decl: Decl, zcu: *Zcu) u32 {
|
||||
assert(decl.has_tv);
|
||||
assert(decl.owns_tv);
|
||||
return decl.val.toType().typeDeclSrcLine(zcu).?;
|
||||
}
|
||||
};
|
||||
|
||||
/// This state is attached to every Decl when Module emit_h is non-null.
|
||||
@@ -3114,9 +3137,9 @@ fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a Depender which is newly outdated or PO, mark all Dependers which may
|
||||
/// in turn be PO, due to a dependency on the original Depender's tyval or IES.
|
||||
fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: InternPool.Depender) !void {
|
||||
/// Given a AnalSubject which is newly outdated or PO, mark all AnalSubjects which may
|
||||
/// in turn be PO, due to a dependency on the original AnalSubject's tyval or IES.
|
||||
fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: InternPool.AnalSubject) !void {
|
||||
var it = zcu.intern_pool.dependencyIterator(switch (maybe_outdated.unwrap()) {
|
||||
.decl => |decl_index| .{ .decl_val = decl_index }, // TODO: also `decl_ref` deps when introduced
|
||||
.func => |func_index| .{ .func_ies = func_index },
|
||||
@@ -3138,12 +3161,12 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: InternP
|
||||
continue;
|
||||
}
|
||||
try zcu.potentially_outdated.putNoClobber(zcu.gpa, po, 1);
|
||||
// This Depender was not already PO, so we must recursively mark its dependers as also PO.
|
||||
// This AnalSubject was not already PO, so we must recursively mark its dependers as also PO.
|
||||
try zcu.markTransitiveDependersPotentiallyOutdated(po);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender {
|
||||
pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.AnalSubject {
|
||||
if (!zcu.comp.debug_incremental) return null;
|
||||
|
||||
if (zcu.outdated.count() == 0 and zcu.potentially_outdated.count() == 0) {
|
||||
@@ -3151,8 +3174,8 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Our goal is to find an outdated Depender which itself has no outdated or
|
||||
// PO dependencies. Most of the time, such a Depender will exist - we track
|
||||
// Our goal is to find an outdated AnalSubject which itself has no outdated or
|
||||
// PO dependencies. Most of the time, such an AnalSubject will exist - we track
|
||||
// them in the `outdated_ready` set for efficiency. However, this is not
|
||||
// necessarily the case, since the Decl dependency graph may contain loops
|
||||
// via mutually recursive definitions:
|
||||
@@ -3174,7 +3197,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender {
|
||||
// `outdated`. This set will be small (number of files changed in this
|
||||
// update), so it's alright for us to just iterate here.
|
||||
for (zcu.outdated_file_root.keys()) |file_decl| {
|
||||
const decl_depender = InternPool.Depender.wrap(.{ .decl = file_decl });
|
||||
const decl_depender = InternPool.AnalSubject.wrap(.{ .decl = file_decl });
|
||||
if (zcu.outdated.contains(decl_depender)) {
|
||||
// Since we didn't hit this in the first loop, this Decl must have
|
||||
// pending dependencies, so is ineligible.
|
||||
@@ -3190,7 +3213,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender {
|
||||
return decl_depender;
|
||||
}
|
||||
|
||||
// There is no single Depender which is ready for re-analysis. Instead, we
|
||||
// There is no single AnalSubject which is ready for re-analysis. Instead, we
|
||||
// must assume that some Decl with PO dependencies is outdated - e.g. in the
|
||||
// above example we arbitrarily pick one of A or B. We should select a Decl,
|
||||
// since a Decl is definitely responsible for the loop in the dependency
|
||||
@@ -3198,7 +3221,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender {
|
||||
|
||||
// The choice of this Decl could have a big impact on how much total
|
||||
// analysis we perform, since if analysis concludes its tyval is unchanged,
|
||||
// then other PO Dependers may be resolved as up-to-date. To hopefully avoid
|
||||
// then other PO AnalSubject may be resolved as up-to-date. To hopefully avoid
|
||||
// doing too much work, let's find a Decl which the most things depend on -
|
||||
// the idea is that this will resolve a lot of loops (but this is only a
|
||||
// heuristic).
|
||||
@@ -3248,7 +3271,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender {
|
||||
chosen_decl_dependers,
|
||||
});
|
||||
|
||||
return InternPool.Depender.wrap(.{ .decl = chosen_decl_idx.? });
|
||||
return InternPool.AnalSubject.wrap(.{ .decl = chosen_decl_idx.? });
|
||||
}
|
||||
|
||||
/// During an incremental update, before semantic analysis, call this to flush all values from
|
||||
@@ -3258,12 +3281,12 @@ pub fn flushRetryableFailures(zcu: *Zcu) !void {
|
||||
for (zcu.retryable_failures.items) |depender| {
|
||||
if (zcu.outdated.contains(depender)) continue;
|
||||
if (zcu.potentially_outdated.fetchSwapRemove(depender)) |kv| {
|
||||
// This Depender was already PO, but we now consider it outdated.
|
||||
// This AnalSubject was already PO, but we now consider it outdated.
|
||||
// Any transitive dependencies are already marked PO.
|
||||
try zcu.outdated.put(gpa, depender, kv.value);
|
||||
continue;
|
||||
}
|
||||
// This Depender was not marked PO, but is now outdated. Mark it as
|
||||
// This AnalSubject was not marked PO, but is now outdated. Mark it as
|
||||
// such, then recursively mark transitive dependencies as PO.
|
||||
try zcu.outdated.put(gpa, depender, 0);
|
||||
try zcu.markTransitiveDependersPotentiallyOutdated(depender);
|
||||
@@ -3433,7 +3456,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
|
||||
// which tries to limit re-analysis to Decls whose previously listed
|
||||
// dependencies are all up-to-date.
|
||||
|
||||
const decl_as_depender = InternPool.Depender.wrap(.{ .decl = decl_index });
|
||||
const decl_as_depender = InternPool.AnalSubject.wrap(.{ .decl = decl_index });
|
||||
const decl_was_outdated = mod.outdated.swapRemove(decl_as_depender) or
|
||||
mod.potentially_outdated.swapRemove(decl_as_depender);
|
||||
|
||||
@@ -3499,7 +3522,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
|
||||
else => |e| {
|
||||
decl.analysis = .sema_failure;
|
||||
try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1);
|
||||
try mod.retryable_failures.append(mod.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
|
||||
try mod.retryable_failures.append(mod.gpa, InternPool.AnalSubject.wrap(.{ .decl = decl_index }));
|
||||
mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
|
||||
mod.gpa,
|
||||
decl.navSrcLoc(mod).upgrade(mod),
|
||||
@@ -3558,7 +3581,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
|
||||
// that's the case, we should remove this function from the binary.
|
||||
if (decl.val.ip_index != func_index) {
|
||||
try zcu.markDependeeOutdated(.{ .func_ies = func_index });
|
||||
ip.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index }));
|
||||
ip.removeDependenciesForDepender(gpa, InternPool.AnalSubject.wrap(.{ .func = func_index }));
|
||||
ip.remove(func_index);
|
||||
@panic("TODO: remove orphaned function from binary");
|
||||
}
|
||||
@@ -3584,7 +3607,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
|
||||
.complete => {},
|
||||
}
|
||||
|
||||
const func_as_depender = InternPool.Depender.wrap(.{ .func = func_index });
|
||||
const func_as_depender = InternPool.AnalSubject.wrap(.{ .func = func_index });
|
||||
const was_outdated = zcu.outdated.swapRemove(func_as_depender) or
|
||||
zcu.potentially_outdated.swapRemove(func_as_depender);
|
||||
|
||||
@@ -3705,7 +3728,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
|
||||
.{@errorName(err)},
|
||||
));
|
||||
func.analysis(ip).state = .codegen_failure;
|
||||
try zcu.retryable_failures.append(zcu.gpa, InternPool.Depender.wrap(.{ .func = func_index }));
|
||||
try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalSubject.wrap(.{ .func = func_index }));
|
||||
},
|
||||
};
|
||||
} else if (zcu.llvm_object) |llvm_object| {
|
||||
@@ -3750,7 +3773,7 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)
|
||||
|
||||
assert(decl.has_tv);
|
||||
|
||||
const func_as_depender = InternPool.Depender.wrap(.{ .func = func_index });
|
||||
const func_as_depender = InternPool.AnalSubject.wrap(.{ .func = func_index });
|
||||
const is_outdated = mod.outdated.contains(func_as_depender) or
|
||||
mod.potentially_outdated.contains(func_as_depender);
|
||||
|
||||
@@ -3834,7 +3857,7 @@ fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespa
|
||||
if (zcu.comp.debug_incremental) {
|
||||
try ip.addDependency(
|
||||
gpa,
|
||||
InternPool.Depender.wrap(.{ .decl = decl_index }),
|
||||
InternPool.AnalSubject.wrap(.{ .decl = decl_index }),
|
||||
.{ .src_hash = tracked_inst },
|
||||
);
|
||||
}
|
||||
@@ -3883,7 +3906,7 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
|
||||
|
||||
if (type_outdated) {
|
||||
// Invalidate the existing type, reusing the decl and namespace.
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = file.root_decl.unwrap().? }));
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalSubject.wrap(.{ .decl = file.root_decl.unwrap().? }));
|
||||
zcu.intern_pool.remove(decl.val.toIntern());
|
||||
decl.val = undefined;
|
||||
_ = try zcu.getFileRootStruct(file.root_decl.unwrap().?, decl.src_namespace, file);
|
||||
@@ -3944,7 +3967,6 @@ fn semaFile(mod: *Module, file: *File) SemaError!void {
|
||||
|
||||
new_decl.name = try file.fullyQualifiedName(mod);
|
||||
new_decl.name_fully_qualified = true;
|
||||
new_decl.src_line = 0;
|
||||
new_decl.is_pub = true;
|
||||
new_decl.is_exported = false;
|
||||
new_decl.alignment = .none;
|
||||
@@ -4075,7 +4097,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
|
||||
break :ip_index .none;
|
||||
};
|
||||
|
||||
mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
|
||||
mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalSubject.wrap(.{ .decl = decl_index }));
|
||||
|
||||
decl.analysis = .in_progress;
|
||||
|
||||
@@ -4301,7 +4323,7 @@ fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
|
||||
// with a new Decl.
|
||||
//
|
||||
// Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalSubject.wrap(.{ .decl = decl_index }));
|
||||
zcu.intern_pool.remove(decl.val.toIntern());
|
||||
decl.analysis = .dependency_failure;
|
||||
return .{
|
||||
@@ -4762,8 +4784,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
|
||||
const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
|
||||
const declaration = extra.data;
|
||||
|
||||
const line = iter.parent_decl.src_line + declaration.line_offset;
|
||||
|
||||
// Every Decl needs a name.
|
||||
const decl_name: InternPool.NullTerminatedString, const kind: Decl.Kind, const is_named_test: bool = switch (declaration.name) {
|
||||
.@"comptime" => info: {
|
||||
@@ -4850,7 +4870,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
|
||||
const was_exported = decl.is_exported;
|
||||
assert(decl.kind == kind); // ZIR tracking should preserve this
|
||||
decl.name = decl_name;
|
||||
decl.src_line = line;
|
||||
decl.is_pub = declaration.flags.is_pub;
|
||||
decl.is_exported = declaration.flags.is_export;
|
||||
break :decl_index .{ was_exported, decl_index };
|
||||
@@ -4860,7 +4879,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
|
||||
const new_decl = zcu.declPtr(new_decl_index);
|
||||
new_decl.kind = kind;
|
||||
new_decl.name = decl_name;
|
||||
new_decl.src_line = line;
|
||||
new_decl.is_pub = declaration.flags.is_pub;
|
||||
new_decl.is_exported = declaration.flags.is_export;
|
||||
new_decl.zir_decl_index = tracked_inst.toOptional();
|
||||
@@ -5008,7 +5026,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
|
||||
const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);
|
||||
defer decl_prog_node.end();
|
||||
|
||||
mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index }));
|
||||
mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalSubject.wrap(.{ .func = func_index }));
|
||||
|
||||
var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
|
||||
defer comptime_err_ret_trace.deinit();
|
||||
@@ -5263,7 +5281,6 @@ pub fn allocateNewDecl(zcu: *Zcu, namespace: Namespace.Index) !Decl.Index {
|
||||
const decl_index = try zcu.intern_pool.createDecl(gpa, .{
|
||||
.name = undefined,
|
||||
.src_namespace = namespace,
|
||||
.src_line = undefined,
|
||||
.has_tv = false,
|
||||
.owns_tv = false,
|
||||
.val = undefined,
|
||||
@@ -5311,14 +5328,12 @@ pub fn errorSetBits(mod: *Module) u16 {
|
||||
pub fn initNewAnonDecl(
|
||||
mod: *Module,
|
||||
new_decl_index: Decl.Index,
|
||||
src_line: u32,
|
||||
val: Value,
|
||||
name: InternPool.NullTerminatedString,
|
||||
) Allocator.Error!void {
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
|
||||
new_decl.name = name;
|
||||
new_decl.src_line = src_line;
|
||||
new_decl.val = val;
|
||||
new_decl.alignment = .none;
|
||||
new_decl.@"linksection" = .none;
|
||||
@@ -5612,7 +5627,7 @@ pub fn linkerUpdateDecl(zcu: *Zcu, decl_index: Decl.Index) !void {
|
||||
.{@errorName(err)},
|
||||
));
|
||||
decl.analysis = .codegen_failure;
|
||||
try zcu.retryable_failures.append(zcu.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
|
||||
try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalSubject.wrap(.{ .decl = decl_index }));
|
||||
},
|
||||
};
|
||||
} else if (zcu.llvm_object) |llvm_object| {
|
||||
|
||||
@@ -1697,7 +1697,7 @@ pub const Object = struct {
|
||||
const file, const subprogram = if (!wip.strip) debug_info: {
|
||||
const file = try o.getDebugFile(namespace.file_scope);
|
||||
|
||||
const line_number = decl.src_line + 1;
|
||||
const line_number = decl.navSrcLine(zcu) + 1;
|
||||
const is_internal_linkage = decl.val.getExternFunc(zcu) == null and
|
||||
!zcu.decl_exports.contains(decl_index);
|
||||
const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu));
|
||||
@@ -1741,7 +1741,7 @@ pub const Object = struct {
|
||||
.sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
|
||||
.file = file,
|
||||
.scope = subprogram,
|
||||
.base_line = dg.decl.src_line,
|
||||
.base_line = dg.decl.navSrcLine(zcu),
|
||||
.prev_dbg_line = 0,
|
||||
.prev_dbg_column = 0,
|
||||
.err_ret_trace = err_ret_trace,
|
||||
@@ -2067,7 +2067,7 @@ pub const Object = struct {
|
||||
try o.builder.metadataString(name),
|
||||
file,
|
||||
scope,
|
||||
owner_decl.src_line + 1, // Line
|
||||
owner_decl.typeSrcLine(mod) + 1, // Line
|
||||
try o.lowerDebugType(int_ty),
|
||||
ty.abiSize(mod) * 8,
|
||||
(ty.abiAlignment(mod).toByteUnits() orelse 0) * 8,
|
||||
@@ -2237,7 +2237,7 @@ pub const Object = struct {
|
||||
try o.builder.metadataString(name),
|
||||
try o.getDebugFile(mod.namespacePtr(owner_decl.src_namespace).file_scope),
|
||||
try o.namespaceToDebugScope(owner_decl.src_namespace),
|
||||
owner_decl.src_line + 1, // Line
|
||||
owner_decl.typeSrcLine(mod) + 1, // Line
|
||||
.none, // Underlying type
|
||||
0, // Size
|
||||
0, // Align
|
||||
@@ -2867,7 +2867,7 @@ pub const Object = struct {
|
||||
try o.builder.metadataString(decl.name.toSlice(&mod.intern_pool)), // TODO use fully qualified name
|
||||
try o.getDebugFile(mod.namespacePtr(decl.src_namespace).file_scope),
|
||||
try o.namespaceToDebugScope(decl.src_namespace),
|
||||
decl.src_line + 1,
|
||||
decl.typeSrcLine(mod) + 1,
|
||||
.none,
|
||||
0,
|
||||
0,
|
||||
@@ -4762,7 +4762,7 @@ pub const DeclGen = struct {
|
||||
else => try o.lowerValue(init_val),
|
||||
}, &o.builder);
|
||||
|
||||
const line_number = decl.src_line + 1;
|
||||
const line_number = decl.navSrcLine(zcu) + 1;
|
||||
const is_internal_linkage = !o.module.decl_exports.contains(decl_index);
|
||||
|
||||
const namespace = zcu.namespacePtr(decl.src_namespace);
|
||||
@@ -5188,7 +5188,7 @@ pub const FuncGen = struct {
|
||||
|
||||
self.file = try o.getDebugFile(namespace.file_scope);
|
||||
|
||||
const line_number = decl.src_line + 1;
|
||||
const line_number = decl.navSrcLine(zcu) + 1;
|
||||
self.inlined = self.wip.debug_location;
|
||||
|
||||
const fqn = try decl.fullyQualifiedName(zcu);
|
||||
@@ -5217,7 +5217,7 @@ pub const FuncGen = struct {
|
||||
o.debug_compile_unit,
|
||||
);
|
||||
|
||||
self.base_line = decl.src_line;
|
||||
self.base_line = decl.navSrcLine(zcu);
|
||||
const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);
|
||||
self.wip.debug_location = .{
|
||||
.location = .{
|
||||
@@ -8857,7 +8857,7 @@ pub const FuncGen = struct {
|
||||
const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
|
||||
const func_index = self.dg.decl.getOwnedFunctionIndex();
|
||||
const func = mod.funcInfo(func_index);
|
||||
const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
|
||||
const lbrace_line = mod.declPtr(func.owner_decl).navSrcLine(mod) + func.lbrace_line + 1;
|
||||
const lbrace_col = func.lbrace_column + 1;
|
||||
|
||||
const debug_parameter = try o.builder.debugParameter(
|
||||
|
||||
@@ -212,7 +212,7 @@ pub const Object = struct {
|
||||
false => .{ .unstructured = .{} },
|
||||
},
|
||||
.current_block_label = undefined,
|
||||
.base_line = decl.src_line,
|
||||
.base_line = decl.navSrcLine(mod),
|
||||
};
|
||||
defer decl_gen.deinit();
|
||||
|
||||
@@ -6345,7 +6345,7 @@ const DeclGen = struct {
|
||||
const decl = mod.funcOwnerDeclPtr(extra.data.func);
|
||||
const old_base_line = self.base_line;
|
||||
defer self.base_line = old_base_line;
|
||||
self.base_line = decl.src_line;
|
||||
self.base_line = decl.navSrcLine(mod);
|
||||
return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
|
||||
}
|
||||
|
||||
|
||||
@@ -948,8 +948,8 @@ pub const DeclState = struct {
|
||||
leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file);
|
||||
}
|
||||
|
||||
const old_src_line: i33 = self.mod.declPtr(old_func_info.owner_decl).src_line;
|
||||
const new_src_line: i33 = self.mod.declPtr(new_func_info.owner_decl).src_line;
|
||||
const old_src_line: i33 = self.mod.declPtr(old_func_info.owner_decl).navSrcLine(self.mod);
|
||||
const new_src_line: i33 = self.mod.declPtr(new_func_info.owner_decl).navSrcLine(self.mod);
|
||||
if (new_src_line != old_src_line) {
|
||||
self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
|
||||
leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line);
|
||||
@@ -1116,11 +1116,11 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
|
||||
decl_state.dbg_line_func = decl.val.toIntern();
|
||||
const func = decl.val.getFunction(mod).?;
|
||||
log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
|
||||
decl.src_line,
|
||||
decl.navSrcLine(mod),
|
||||
func.lbrace_line,
|
||||
func.rbrace_line,
|
||||
});
|
||||
const line: u28 = @intCast(decl.src_line + func.lbrace_line);
|
||||
const line: u28 = @intCast(decl.navSrcLine(mod) + func.lbrace_line);
|
||||
|
||||
dbg_line_buffer.appendSliceAssumeCapacity(&.{
|
||||
DW.LNS.extended_op,
|
||||
@@ -1702,11 +1702,11 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.D
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const func = decl.val.getFunction(mod).?;
|
||||
log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
|
||||
decl.src_line,
|
||||
decl.navSrcLine(mod),
|
||||
func.lbrace_line,
|
||||
func.rbrace_line,
|
||||
});
|
||||
const line: u28 = @intCast(decl.src_line + func.lbrace_line);
|
||||
const line: u28 = @intCast(decl.navSrcLine(mod) + func.lbrace_line);
|
||||
var data: [4]u8 = undefined;
|
||||
leb128.writeUnsignedFixed(4, &data, line);
|
||||
|
||||
|
||||
@@ -583,7 +583,7 @@ const Writer = struct {
|
||||
|
||||
.reify => {
|
||||
const inst_data = self.code.extraData(Zir.Inst.Reify, extended.operand).data;
|
||||
try stream.print("{d}, ", .{inst_data.src_line});
|
||||
try stream.print("line({d}), ", .{inst_data.src_line});
|
||||
try self.writeInstRef(stream, inst_data.operand);
|
||||
try stream.writeAll(")) ");
|
||||
const prev_parent_decl_node = self.parent_decl_node;
|
||||
@@ -2749,7 +2749,7 @@ const Writer = struct {
|
||||
extra.data.src_hash_3,
|
||||
};
|
||||
const src_hash_bytes: [16]u8 = @bitCast(src_hash_arr);
|
||||
try stream.print(" line(+{d}) hash({})", .{ extra.data.line_offset, std.fmt.fmtSliceHexLower(&src_hash_bytes) });
|
||||
try stream.print(" line({d}) hash({})", .{ extra.data.src_line, std.fmt.fmtSliceHexLower(&src_hash_bytes) });
|
||||
|
||||
{
|
||||
const bodies = extra.data.getBodies(@intCast(extra.end), self.code);
|
||||
|
||||
30
src/type.zig
30
src/type.zig
@@ -11,6 +11,7 @@ const target_util = @import("target.zig");
|
||||
const Sema = @import("Sema.zig");
|
||||
const InternPool = @import("InternPool.zig");
|
||||
const Alignment = InternPool.Alignment;
|
||||
const Zir = std.zig.Zir;
|
||||
|
||||
/// Both types and values are canonically represented by a single 32-bit integer
|
||||
/// which is an index into an `InternPool` data structure.
|
||||
@@ -3340,7 +3341,7 @@ pub const Type = struct {
|
||||
.struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
|
||||
.declared => |d| d.zir_index,
|
||||
.reified => |r| r.zir_index,
|
||||
.generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index, // must be declared since we can't generate tags when reifying
|
||||
.generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
|
||||
.empty_struct => return null,
|
||||
},
|
||||
else => return null,
|
||||
@@ -3440,6 +3441,33 @@ pub const Type = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 {
|
||||
const ip = &zcu.intern_pool;
|
||||
const tracked = switch (ip.indexToKey(ty.toIntern())) {
|
||||
.struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
|
||||
.declared => |d| d.zir_index,
|
||||
.reified => |r| r.zir_index,
|
||||
.generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
|
||||
.empty_struct => return null,
|
||||
},
|
||||
else => return null,
|
||||
};
|
||||
const info = tracked.resolveFull(&zcu.intern_pool);
|
||||
const file = zcu.import_table.values()[zcu.path_digest_map.getIndex(info.path_digest).?];
|
||||
assert(file.zir_loaded);
|
||||
const zir = file.zir;
|
||||
const inst = zir.instructions.get(@intFromEnum(info.inst));
|
||||
assert(inst.tag == .extended);
|
||||
return switch (inst.data.extended.opcode) {
|
||||
.struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_line,
|
||||
.union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_line,
|
||||
.enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_line,
|
||||
.opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_line,
|
||||
.reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.src_line,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
/// Given a namespace type, returns its list of caotured values.
|
||||
pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
Reference in New Issue
Block a user