diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-04-27 18:36:12 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-28 16:57:01 -0700 |
| commit | f86469bc5eea2b7bd95222d00a11bd287bfdfedf (patch) | |
| tree | c34ef71820e4c7b962a631f2b9cdecdff3f5aa79 /src/link | |
| parent | fa6bb4b662155e4d6a61cc551b5d02a2a7d5d144 (diff) | |
| download | zig-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.zig | 68 | ||||
| -rw-r--r-- | src/link/Coff.zig | 10 | ||||
| -rw-r--r-- | src/link/Elf.zig | 15 | ||||
| -rw-r--r-- | src/link/MachO.zig | 15 | ||||
| -rw-r--r-- | src/link/MachO/DebugSymbols.zig | 10 | ||||
| -rw-r--r-- | src/link/SpirV.zig | 10 | ||||
| -rw-r--r-- | src/link/Wasm.zig | 16 |
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 |
