diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-10-26 20:32:16 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-10-26 20:32:16 -0700 |
| commit | 4bc88dd11641a664d80b00ad784bafc6da776697 (patch) | |
| tree | 0dfff49ae93d5826a0c10e3819a1225e4f992693 /src/link.zig | |
| parent | ba9e38847a097777370b4721780d5dbefda1b12f (diff) | |
| download | zig-4bc88dd11641a664d80b00ad784bafc6da776697.tar.gz zig-4bc88dd11641a664d80b00ad784bafc6da776697.zip | |
link: support exporting constant values without a Decl
The main motivating change here is to prevent the creation of a fake
Decl object by the frontend in order to `@export()` a value.
Instead, `link.updateDeclExports` is renamed to `link.updateExports` and
accepts a tagged union which can be either a Decl.Index or a
InternPool.Index.
Diffstat (limited to 'src/link.zig')
| -rw-r--r-- | src/link.zig | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/src/link.zig b/src/link.zig index 6e5c809f62..1648d6a63e 100644 --- a/src/link.zig +++ b/src/link.zig @@ -587,7 +587,7 @@ pub const File = struct { } } - /// May be called before or after updateDeclExports for any given Decl. + /// May be called before or after updateExports for any given Decl. pub fn updateDecl(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void { const decl = module.declPtr(decl_index); assert(decl.has_tv); @@ -609,7 +609,7 @@ pub const File = struct { } } - /// May be called before or after updateDeclExports for any given Decl. + /// May be called before or after updateExports for any given Decl. pub fn updateFunc(base: *File, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) UpdateDeclError!void { if (build_options.only_c) { assert(base.tag == .c); @@ -882,33 +882,34 @@ pub const File = struct { } } - pub const UpdateDeclExportsError = error{ + pub const UpdateExportsError = error{ OutOfMemory, AnalysisFail, }; + /// This is called for every exported thing. `exports` is almost always + /// a list of size 1, meaning that `exported` is exported once. However, it is possible + /// to export the same thing with multiple different symbol names (aliases). /// May be called before or after updateDecl for any given Decl. - pub fn updateDeclExports( + pub fn updateExports( base: *File, module: *Module, - decl_index: Module.Decl.Index, + exported: Module.Exported, exports: []const *Module.Export, - ) UpdateDeclExportsError!void { - const decl = module.declPtr(decl_index); - assert(decl.has_tv); + ) UpdateExportsError!void { if (build_options.only_c) { assert(base.tag == .c); - return @fieldParentPtr(C, "base", base).updateDeclExports(module, decl_index, exports); + return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports); } switch (base.tag) { - .coff => return @fieldParentPtr(Coff, "base", base).updateDeclExports(module, decl_index, exports), - .elf => return @fieldParentPtr(Elf, "base", base).updateDeclExports(module, decl_index, exports), - .macho => return @fieldParentPtr(MachO, "base", base).updateDeclExports(module, decl_index, exports), - .c => return @fieldParentPtr(C, "base", base).updateDeclExports(module, decl_index, exports), - .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclExports(module, decl_index, exports), - .spirv => return @fieldParentPtr(SpirV, "base", base).updateDeclExports(module, decl_index, exports), - .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclExports(module, decl_index, exports), - .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDeclExports(module, decl_index, exports), + .coff => return @fieldParentPtr(Coff, "base", base).updateExports(module, exported, exports), + .elf => return @fieldParentPtr(Elf, "base", base).updateExports(module, exported, exports), + .macho => return @fieldParentPtr(MachO, "base", base).updateExports(module, exported, exports), + .c => return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports), + .wasm => return @fieldParentPtr(Wasm, "base", base).updateExports(module, exported, exports), + .spirv => return @fieldParentPtr(SpirV, "base", base).updateExports(module, exported, exports), + .plan9 => return @fieldParentPtr(Plan9, "base", base).updateExports(module, exported, exports), + .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateExports(module, exported, exports), } } @@ -968,6 +969,20 @@ pub const File = struct { } } + pub fn deleteDeclExport(base: *File, decl_index: Module.Decl.Index, name: InternPool.NullTerminatedString) !void { + if (build_options.only_c) unreachable; + switch (base.tag) { + .coff => return @fieldParentPtr(Coff, "base", base).deleteDeclExport(decl_index, name), + .elf => return @fieldParentPtr(Elf, "base", base).deleteDeclExport(decl_index, name), + .macho => return @fieldParentPtr(MachO, "base", base).deleteDeclExport(decl_index, name), + .plan9 => {}, + .c => {}, + .wasm => return @fieldParentPtr(Wasm, "base", base).deleteDeclExport(decl_index), + .spirv => {}, + .nvptx => {}, + } + } + /// This function is called by the frontend before flush(). It communicates that /// `options.bin_file.emit` directory needs to be renamed from /// `[zig-cache]/tmp/[random]` to `[zig-cache]/o/[digest]`. |
