aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-04-27 18:36:12 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-04-28 16:57:01 -0700
commitf86469bc5eea2b7bd95222d00a11bd287bfdfedf (patch)
treec34ef71820e4c7b962a631f2b9cdecdff3f5aa79 /src/link
parentfa6bb4b662155e4d6a61cc551b5d02a2a7d5d144 (diff)
downloadzig-f86469bc5eea2b7bd95222d00a11bd287bfdfedf.tar.gz
zig-f86469bc5eea2b7bd95222d00a11bd287bfdfedf.zip
stage2: semaDecl properly analyzes the decl block
Also flattened out Decl TypedValue fields into ty, val, has_tv and add relevant fields to Decl for alignment and link section.
Diffstat (limited to 'src/link')
-rw-r--r--src/link/C.zig68
-rw-r--r--src/link/Coff.zig10
-rw-r--r--src/link/Elf.zig15
-rw-r--r--src/link/MachO.zig15
-rw-r--r--src/link/MachO/DebugSymbols.zig10
-rw-r--r--src/link/SpirV.zig10
-rw-r--r--src/link/Wasm.zig16
7 files changed, 69 insertions, 75 deletions
diff --git a/src/link/C.zig b/src/link/C.zig
index 1245ead602..5cb704befd 100644
--- a/src/link/C.zig
+++ b/src/link/C.zig
@@ -206,34 +206,30 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
// generate, rather than querying here, be faster?
for (self.decl_table.items()) |kv| {
const decl = kv.key;
- switch (decl.typed_value) {
- .most_recent => |tvm| {
- const buf = buf: {
- if (tvm.typed_value.val.castTag(.function)) |_| {
- var it = decl.fn_link.c.typedefs.iterator();
- while (it.next()) |new| {
- if (typedefs.get(new.key)) |previous| {
- try err_typedef_writer.print("typedef {s} {s};\n", .{ previous, new.value.name });
- } else {
- try typedefs.ensureCapacity(typedefs.capacity() + 1);
- try err_typedef_writer.writeAll(new.value.rendered);
- typedefs.putAssumeCapacityNoClobber(new.key, new.value.name);
- }
- }
- fn_count += 1;
- break :buf decl.fn_link.c.fwd_decl.items;
+ if (!decl.has_tv) continue;
+ const buf = buf: {
+ if (decl.val.castTag(.function)) |_| {
+ var it = decl.fn_link.c.typedefs.iterator();
+ while (it.next()) |new| {
+ if (typedefs.get(new.key)) |previous| {
+ try err_typedef_writer.print("typedef {s} {s};\n", .{ previous, new.value.name });
} else {
- break :buf decl.link.c.code.items;
+ try typedefs.ensureCapacity(typedefs.capacity() + 1);
+ try err_typedef_writer.writeAll(new.value.rendered);
+ typedefs.putAssumeCapacityNoClobber(new.key, new.value.name);
}
- };
- all_buffers.appendAssumeCapacity(.{
- .iov_base = buf.ptr,
- .iov_len = buf.len,
- });
- file_size += buf.len;
- },
- .never_succeeded => continue,
- }
+ }
+ fn_count += 1;
+ break :buf decl.fn_link.c.fwd_decl.items;
+ } else {
+ break :buf decl.link.c.code.items;
+ }
+ };
+ all_buffers.appendAssumeCapacity(.{
+ .iov_base = buf.ptr,
+ .iov_len = buf.len,
+ });
+ file_size += buf.len;
}
err_typedef_item.* = .{
@@ -246,18 +242,14 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
try all_buffers.ensureCapacity(all_buffers.items.len + fn_count);
for (self.decl_table.items()) |kv| {
const decl = kv.key;
- switch (decl.typed_value) {
- .most_recent => |tvm| {
- if (tvm.typed_value.val.castTag(.function)) |_| {
- const buf = decl.link.c.code.items;
- all_buffers.appendAssumeCapacity(.{
- .iov_base = buf.ptr,
- .iov_len = buf.len,
- });
- file_size += buf.len;
- }
- },
- .never_succeeded => continue,
+ if (!decl.has_tv) continue;
+ if (decl.val.castTag(.function)) |_| {
+ const buf = decl.link.c.code.items;
+ all_buffers.appendAssumeCapacity(.{
+ .iov_base = buf.ptr,
+ .iov_len = buf.len,
+ });
+ file_size += buf.len;
}
}
diff --git a/src/link/Coff.zig b/src/link/Coff.zig
index 33c37f8efe..374f37858e 100644
--- a/src/link/Coff.zig
+++ b/src/link/Coff.zig
@@ -662,15 +662,17 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {
if (build_options.have_llvm)
if (self.llvm_object) |llvm_object| return try llvm_object.updateDecl(module, decl);
- const typed_value = decl.typed_value.most_recent.typed_value;
- if (typed_value.val.tag() == .extern_fn) {
+ if (decl.val.tag() == .extern_fn) {
return; // TODO Should we do more when front-end analyzed extern decl?
}
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
defer code_buffer.deinit();
- const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .none);
+ const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
+ .ty = decl.ty,
+ .val = decl.val,
+ }, &code_buffer, .none);
const code = switch (res) {
.externally_managed => |x| x,
.appended => code_buffer.items,
@@ -681,7 +683,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {
},
};
- const required_alignment = typed_value.ty.abiAlignment(self.base.options.target);
+ const required_alignment = decl.ty.abiAlignment(self.base.options.target);
const curr_size = decl.link.coff.size;
if (curr_size != 0) {
const capacity = decl.link.coff.capacity();
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 173ffdab68..7fbf17015e 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -2191,8 +2191,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
if (build_options.have_llvm)
if (self.llvm_object) |llvm_object| return try llvm_object.updateDecl(module, decl);
- const typed_value = decl.typed_value.most_recent.typed_value;
- if (typed_value.val.tag() == .extern_fn) {
+ if (decl.val.tag() == .extern_fn) {
return; // TODO Should we do more when front-end analyzed extern decl?
}
@@ -2214,7 +2213,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
dbg_info_type_relocs.deinit(self.base.allocator);
}
- const is_fn: bool = switch (typed_value.ty.zigTypeTag()) {
+ const is_fn: bool = switch (decl.ty.zigTypeTag()) {
.Fn => true,
else => false,
};
@@ -2270,7 +2269,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];
try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 25 + decl_name_with_null.len);
- const fn_ret_type = typed_value.ty.fnReturnType();
+ const fn_ret_type = decl.ty.fnReturnType();
const fn_ret_has_bits = fn_ret_type.hasCodeGenBits();
if (fn_ret_has_bits) {
dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram);
@@ -2299,7 +2298,10 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
} else {
// TODO implement .debug_info for global variables
}
- const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{
+ const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
+ .ty = decl.ty,
+ .val = decl.val,
+ }, &code_buffer, .{
.dwarf = .{
.dbg_line = &dbg_line_buffer,
.dbg_info = &dbg_info_buffer,
@@ -2316,7 +2318,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
},
};
- const required_alignment = typed_value.ty.abiAlignment(self.base.options.target);
+ const required_alignment = decl.ty.abiAlignment(self.base.options.target);
const stt_bits: u8 = if (is_fn) elf.STT_FUNC else elf.STT_OBJECT;
@@ -2678,7 +2680,6 @@ pub fn updateDeclExports(
defer tracy.end();
try self.global_symbols.ensureCapacity(self.base.allocator, self.global_symbols.items.len + exports.len);
- const typed_value = decl.typed_value.most_recent.typed_value;
if (decl.link.elf.local_sym_index == 0) return;
const decl_sym = self.local_symbols.items[decl.link.elf.local_sym_index];
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index aaf88ad815..f6a0a9a6b8 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -1138,8 +1138,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
const tracy = trace(@src());
defer tracy.end();
- const typed_value = decl.typed_value.most_recent.typed_value;
- if (typed_value.val.tag() == .extern_fn) {
+ if (decl.val.tag() == .extern_fn) {
return; // TODO Should we do more when front-end analyzed extern decl?
}
@@ -1160,7 +1159,10 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
}
const res = if (debug_buffers) |*dbg|
- try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{
+ try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
+ .ty = decl.ty,
+ .val = decl.val,
+ }, &code_buffer, .{
.dwarf = .{
.dbg_line = &dbg.dbg_line_buffer,
.dbg_info = &dbg.dbg_info_buffer,
@@ -1168,7 +1170,10 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
},
})
else
- try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .none);
+ try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
+ .ty = decl.ty,
+ .val = decl.val,
+ }, &code_buffer, .none);
const code = switch (res) {
.externally_managed => |x| x,
@@ -1184,7 +1189,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
},
};
- const required_alignment = typed_value.ty.abiAlignment(self.base.options.target);
+ const required_alignment = decl.ty.abiAlignment(self.base.options.target);
assert(decl.link.macho.local_sym_index != 0); // Caller forgot to call allocateDeclIndexes()
const symbol = &self.locals.items[decl.link.macho.local_sym_index];
diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig
index 4c6b71eed4..d399fa98b7 100644
--- a/src/link/MachO/DebugSymbols.zig
+++ b/src/link/MachO/DebugSymbols.zig
@@ -946,8 +946,8 @@ pub fn initDeclDebugBuffers(
var dbg_info_buffer = std.ArrayList(u8).init(allocator);
var dbg_info_type_relocs: link.File.DbgInfoTypeRelocsTable = .{};
- const typed_value = decl.typed_value.most_recent.typed_value;
- switch (typed_value.ty.zigTypeTag()) {
+ assert(decl.has_tv);
+ switch (decl.ty.zigTypeTag()) {
.Fn => {
// For functions we need to add a prologue to the debug line program.
try dbg_line_buffer.ensureCapacity(26);
@@ -999,7 +999,7 @@ pub fn initDeclDebugBuffers(
const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];
try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 27 + decl_name_with_null.len);
- const fn_ret_type = typed_value.ty.fnReturnType();
+ const fn_ret_type = decl.ty.fnReturnType();
const fn_ret_has_bits = fn_ret_type.hasCodeGenBits();
if (fn_ret_has_bits) {
dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram);
@@ -1058,8 +1058,8 @@ pub fn commitDeclDebugInfo(
const symbol = self.base.locals.items[decl.link.macho.local_sym_index];
const text_block = &decl.link.macho;
// If the Decl is a function, we need to update the __debug_line program.
- const typed_value = decl.typed_value.most_recent.typed_value;
- switch (typed_value.ty.zigTypeTag()) {
+ assert(decl.has_tv);
+ switch (decl.ty.zigTypeTag()) {
.Fn => {
// Perform the relocations based on vaddr.
{
diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig
index 5d4e50ef25..09045ac91a 100644
--- a/src/link/SpirV.zig
+++ b/src/link/SpirV.zig
@@ -179,13 +179,9 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
for (self.decl_table.items()) |entry| {
const decl = entry.key;
- switch (decl.typed_value) {
- .most_recent => |tvm| {
- const fn_data = &decl.fn_link.spirv;
- all_buffers.appendAssumeCapacity(wordsToIovConst(fn_data.code.items));
- },
- .never_succeeded => continue,
- }
+ if (!decl.has_tv) continue;
+ const fn_data = &decl.fn_link.spirv;
+ all_buffers.appendAssumeCapacity(wordsToIovConst(fn_data.code.items));
}
var file_size: u64 = 0;
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index 2dd15db1d4..41b08b09d6 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -175,9 +175,8 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {
self.offset_table.items[block.offset_index] = 0;
- const typed_value = decl.typed_value.most_recent.typed_value;
- if (typed_value.ty.zigTypeTag() == .Fn) {
- switch (typed_value.val.tag()) {
+ if (decl.ty.zigTypeTag() == .Fn) {
+ switch (decl.val.tag()) {
// dependent on function type, appends it to the correct list
.function => try self.funcs.append(self.base.allocator, decl),
.extern_fn => try self.ext_funcs.append(self.base.allocator, decl),
@@ -191,7 +190,6 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {
pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
std.debug.assert(decl.link.wasm.init); // Must call allocateDeclIndexes()
- const typed_value = decl.typed_value.most_recent.typed_value;
const fn_data = &decl.fn_link.wasm;
fn_data.functype.items.len = 0;
fn_data.code.items.len = 0;
@@ -210,7 +208,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
defer context.deinit();
// generate the 'code' section for the function declaration
- const result = context.gen(typed_value) catch |err| switch (err) {
+ const result = context.gen(.{ .ty = decl.ty, .val = decl.val }) catch |err| switch (err) {
error.CodegenFail => {
decl.analysis = .codegen_failure;
try module.failed_decls.put(module.gpa, decl, context.err_msg);
@@ -228,7 +226,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
fn_data.functype = context.func_type_data.toUnmanaged();
const block = &decl.link.wasm;
- if (typed_value.ty.zigTypeTag() == .Fn) {
+ if (decl.ty.zigTypeTag() == .Fn) {
// as locals are patched afterwards, the offsets of funcidx's are off,
// here we update them to correct them
for (fn_data.idx_refs.items) |*func| {
@@ -262,7 +260,7 @@ pub fn updateDeclExports(
pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void {
if (self.getFuncidx(decl)) |func_idx| {
- switch (decl.typed_value.most_recent.typed_value.val.tag()) {
+ switch (decl.val.tag()) {
.function => _ = self.funcs.swapRemove(func_idx),
.extern_fn => _ = self.ext_funcs.swapRemove(func_idx),
else => unreachable,
@@ -429,7 +427,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
try leb.writeULEB128(writer, @intCast(u32, exprt.options.name.len));
try writer.writeAll(exprt.options.name);
- switch (exprt.exported_decl.typed_value.most_recent.typed_value.ty.zigTypeTag()) {
+ switch (exprt.exported_decl.ty.zigTypeTag()) {
.Fn => {
// Type of the export
try writer.writeByte(wasm.externalKind(.function));
@@ -802,7 +800,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
/// TODO: we could maintain a hash map to potentially make this simpler
fn getFuncidx(self: Wasm, decl: *Module.Decl) ?u32 {
var offset: u32 = 0;
- const slice = switch (decl.typed_value.most_recent.typed_value.val.tag()) {
+ const slice = switch (decl.val.tag()) {
.function => blk: {
// when the target is a regular function, we have to calculate
// the offset of where the index starts