| author | |
| committer | |
| log | 458943e324e81762a9a2aa839d2fa3c851068e6f |
| tree | e806a09ac101998495d1c35947c14935923ad33a |
| parent | ed63d6c7fdbdc3c508457ca792436595dd443ac8 |
| parent | 1ff9a18cd327027164073f1ebf9c2cca6c3de876 |
| signature |
Stage1: Add Visibility field to ExportOptions.4 files changed, 45 insertions(+), 7 deletions(-)
lib/std/builtin.zig+9| ... | ... | @@ -68,6 +68,14 @@ pub const GlobalLinkage = enum { |
| 68 | 68 | LinkOnce, |
| 69 | 69 | }; |
| 70 | 70 | |
| 71 | /// This data structure is used by the Zig language code generation and | |
| 72 | /// therefore must be kept in sync with the compiler implementation. | |
| 73 | pub const SymbolVisibility = enum { | |
| 74 | default, | |
| 75 | hidden, | |
| 76 | protected, | |
| 77 | }; | |
| 78 | ||
| 71 | 79 | /// This data structure is used by the Zig language code generation and |
| 72 | 80 | /// therefore must be kept in sync with the compiler implementation. |
| 73 | 81 | pub const AtomicOrder = enum { |
| ... | ... | @@ -655,6 +663,7 @@ pub const ExportOptions = struct { |
| 655 | 663 | name: []const u8, |
| 656 | 664 | linkage: GlobalLinkage = .Strong, |
| 657 | 665 | section: ?[]const u8 = null, |
| 666 | visibility: SymbolVisibility = .default, | |
| 658 | 667 | }; |
| 659 | 668 | |
| 660 | 669 | /// This data structure is used by the Zig language code generation and |
src/Sema.zig+22-7| ... | ... | @@ -4348,6 +4348,7 @@ pub fn analyzeExport( |
| 4348 | 4348 | .name = symbol_name, |
| 4349 | 4349 | .linkage = borrowed_options.linkage, |
| 4350 | 4350 | .section = section, |
| 4351 | .visibility = borrowed_options.visibility, | |
| 4351 | 4352 | }, |
| 4352 | 4353 | .src = src, |
| 4353 | 4354 | .link = switch (mod.comp.bin_file.tag) { |
| ... | ... | @@ -14998,23 +14999,37 @@ fn resolveExportOptions( |
| 14998 | 14999 | const air_ref = sema.resolveInst(zir_ref); |
| 14999 | 15000 | const options = try sema.coerce(block, export_options_ty, air_ref, src); |
| 15000 | 15001 | |
| 15001 | const name = try sema.fieldVal(block, src, options, "name", src); | |
| 15002 | const name_val = try sema.resolveConstValue(block, src, name); | |
| 15002 | const name_operand = try sema.fieldVal(block, src, options, "name", src); | |
| 15003 | const name_val = try sema.resolveConstValue(block, src, name_operand); | |
| 15004 | const name_ty = Type.initTag(.const_slice_u8); | |
| 15005 | const name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod); | |
| 15003 | 15006 | |
| 15004 | const linkage = try sema.fieldVal(block, src, options, "linkage", src); | |
| 15005 | const linkage_val = try sema.resolveConstValue(block, src, linkage); | |
| 15007 | const linkage_operand = try sema.fieldVal(block, src, options, "linkage", src); | |
| 15008 | const linkage_val = try sema.resolveConstValue(block, src, linkage_operand); | |
| 15009 | const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage); | |
| 15006 | 15010 | |
| 15007 | 15011 | const section = try sema.fieldVal(block, src, options, "section", src); |
| 15008 | 15012 | const section_val = try sema.resolveConstValue(block, src, section); |
| 15009 | 15013 | |
| 15014 | const visibility_operand = try sema.fieldVal(block, src, options, "visibility", src); | |
| 15015 | const visibility_val = try sema.resolveConstValue(block, src, visibility_operand); | |
| 15016 | const visibility = visibility_val.toEnum(std.builtin.SymbolVisibility); | |
| 15017 | ||
| 15018 | if (visibility != .default and linkage == .Internal) { | |
| 15019 | return sema.fail(block, src, "symbol '{s}' exported with internal linkage has non-default visibility {s}", .{ | |
| 15020 | name, @tagName(visibility), | |
| 15021 | }); | |
| 15022 | } | |
| 15023 | ||
| 15010 | 15024 | if (!section_val.isNull()) { |
| 15011 | 15025 | return sema.fail(block, src, "TODO: implement exporting with linksection", .{}); |
| 15012 | 15026 | } |
| 15013 | const name_ty = Type.initTag(.const_slice_u8); | |
| 15027 | ||
| 15014 | 15028 | return std.builtin.ExportOptions{ |
| 15015 | .name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod), | |
| 15016 | .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage), | |
| 15029 | .name = name, | |
| 15030 | .linkage = linkage, | |
| 15017 | 15031 | .section = null, // TODO |
| 15032 | .visibility = visibility, | |
| 15018 | 15033 | }; |
| 15019 | 15034 | } |
| 15020 | 15035 |
src/codegen/llvm.zig+5| ... | ... | @@ -808,6 +808,11 @@ pub const Object = struct { |
| 808 | 808 | .Weak => llvm_global.setLinkage(.WeakODR), |
| 809 | 809 | .LinkOnce => llvm_global.setLinkage(.LinkOnceODR), |
| 810 | 810 | } |
| 811 | switch (exports[0].options.visibility) { | |
| 812 | .default => llvm_global.setVisibility(.Default), | |
| 813 | .hidden => llvm_global.setVisibility(.Hidden), | |
| 814 | .protected => llvm_global.setVisibility(.Protected), | |
| 815 | } | |
| 811 | 816 | if (decl.val.castTag(.variable)) |variable| { |
| 812 | 817 | if (variable.data.is_threadlocal) { |
| 813 | 818 | llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel); |
src/codegen/llvm/bindings.zig+9| ... | ... | @@ -117,6 +117,9 @@ pub const Value = opaque { |
| 117 | 117 | pub const setLinkage = LLVMSetLinkage; |
| 118 | 118 | extern fn LLVMSetLinkage(Global: *const Value, Linkage: Linkage) void; |
| 119 | 119 | |
| 120 | pub const setVisibility = LLVMSetVisibility; | |
| 121 | extern fn LLVMSetVisibility(Global: *const Value, Linkage: Visibility) void; | |
| 122 | ||
| 120 | 123 | pub const setUnnamedAddr = LLVMSetUnnamedAddr; |
| 121 | 124 | extern fn LLVMSetUnnamedAddr(Global: *const Value, HasUnnamedAddr: Bool) void; |
| 122 | 125 | |
| ... | ... | @@ -1324,6 +1327,12 @@ pub const Linkage = enum(c_uint) { |
| 1324 | 1327 | LinkerPrivateWeak, |
| 1325 | 1328 | }; |
| 1326 | 1329 | |
| 1330 | pub const Visibility = enum(c_uint) { | |
| 1331 | Default, | |
| 1332 | Hidden, | |
| 1333 | Protected, | |
| 1334 | }; | |
| 1335 | ||
| 1327 | 1336 | pub const ThreadLocalMode = enum(c_uint) { |
| 1328 | 1337 | NotThreadLocal, |
| 1329 | 1338 | GeneralDynamicTLSModel, |