| 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,6 +68,14 @@ pub const GlobalLinkage = enum { |
| 68 | LinkOnce, | 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 | /// This data structure is used by the Zig language code generation and | 79 | /// This data structure is used by the Zig language code generation and |
| 72 | /// therefore must be kept in sync with the compiler implementation. | 80 | /// therefore must be kept in sync with the compiler implementation. |
| 73 | pub const AtomicOrder = enum { | 81 | pub const AtomicOrder = enum { |
| ... | @@ -655,6 +663,7 @@ pub const ExportOptions = struct { | ... | @@ -655,6 +663,7 @@ pub const ExportOptions = struct { |
| 655 | name: []const u8, | 663 | name: []const u8, |
| 656 | linkage: GlobalLinkage = .Strong, | 664 | linkage: GlobalLinkage = .Strong, |
| 657 | section: ?[]const u8 = null, | 665 | section: ?[]const u8 = null, |
| 666 | visibility: SymbolVisibility = .default, | ||
| 658 | }; | 667 | }; |
| 659 | 668 | ||
| 660 | /// This data structure is used by the Zig language code generation and | 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,6 +4348,7 @@ pub fn analyzeExport( |
| 4348 | .name = symbol_name, | 4348 | .name = symbol_name, |
| 4349 | .linkage = borrowed_options.linkage, | 4349 | .linkage = borrowed_options.linkage, |
| 4350 | .section = section, | 4350 | .section = section, |
| 4351 | .visibility = borrowed_options.visibility, | ||
| 4351 | }, | 4352 | }, |
| 4352 | .src = src, | 4353 | .src = src, |
| 4353 | .link = switch (mod.comp.bin_file.tag) { | 4354 | .link = switch (mod.comp.bin_file.tag) { |
| ... | @@ -14998,23 +14999,37 @@ fn resolveExportOptions( | ... | @@ -14998,23 +14999,37 @@ fn resolveExportOptions( |
| 14998 | const air_ref = sema.resolveInst(zir_ref); | 14999 | const air_ref = sema.resolveInst(zir_ref); |
| 14999 | const options = try sema.coerce(block, export_options_ty, air_ref, src); | 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_operand = try sema.fieldVal(block, src, options, "name", src); |
| 15002 | const name_val = try sema.resolveConstValue(block, src, name); | 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); | 15007 | const linkage_operand = try sema.fieldVal(block, src, options, "linkage", src); |
| 15005 | const linkage_val = try sema.resolveConstValue(block, src, linkage); | 15008 | const linkage_val = try sema.resolveConstValue(block, src, linkage_operand); |
| 15009 | const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage); | ||
| 15006 | 15010 | ||
| 15007 | const section = try sema.fieldVal(block, src, options, "section", src); | 15011 | const section = try sema.fieldVal(block, src, options, "section", src); |
| 15008 | const section_val = try sema.resolveConstValue(block, src, section); | 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 | if (!section_val.isNull()) { | 15024 | if (!section_val.isNull()) { |
| 15011 | return sema.fail(block, src, "TODO: implement exporting with linksection", .{}); | 15025 | return sema.fail(block, src, "TODO: implement exporting with linksection", .{}); |
| 15012 | } | 15026 | } |
| 15013 | const name_ty = Type.initTag(.const_slice_u8); | 15027 | |
| 15014 | return std.builtin.ExportOptions{ | 15028 | return std.builtin.ExportOptions{ |
| 15015 | .name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod), | 15029 | .name = name, |
| 15016 | .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage), | 15030 | .linkage = linkage, |
| 15017 | .section = null, // TODO | 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,6 +808,11 @@ pub const Object = struct { |
| 808 | .Weak => llvm_global.setLinkage(.WeakODR), | 808 | .Weak => llvm_global.setLinkage(.WeakODR), |
| 809 | .LinkOnce => llvm_global.setLinkage(.LinkOnceODR), | 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 | if (decl.val.castTag(.variable)) |variable| { | 816 | if (decl.val.castTag(.variable)) |variable| { |
| 812 | if (variable.data.is_threadlocal) { | 817 | if (variable.data.is_threadlocal) { |
| 813 | llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel); | 818 | llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel); |
src/codegen/llvm/bindings.zig+9| ... | @@ -117,6 +117,9 @@ pub const Value = opaque { | ... | @@ -117,6 +117,9 @@ pub const Value = opaque { |
| 117 | pub const setLinkage = LLVMSetLinkage; | 117 | pub const setLinkage = LLVMSetLinkage; |
| 118 | extern fn LLVMSetLinkage(Global: *const Value, Linkage: Linkage) void; | 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 | pub const setUnnamedAddr = LLVMSetUnnamedAddr; | 123 | pub const setUnnamedAddr = LLVMSetUnnamedAddr; |
| 121 | extern fn LLVMSetUnnamedAddr(Global: *const Value, HasUnnamedAddr: Bool) void; | 124 | extern fn LLVMSetUnnamedAddr(Global: *const Value, HasUnnamedAddr: Bool) void; |
| 122 | 125 | ||
| ... | @@ -1324,6 +1327,12 @@ pub const Linkage = enum(c_uint) { | ... | @@ -1324,6 +1327,12 @@ pub const Linkage = enum(c_uint) { |
| 1324 | LinkerPrivateWeak, | 1327 | LinkerPrivateWeak, |
| 1325 | }; | 1328 | }; |
| 1326 | 1329 | ||
| 1330 | pub const Visibility = enum(c_uint) { | ||
| 1331 | Default, | ||
| 1332 | Hidden, | ||
| 1333 | Protected, | ||
| 1334 | }; | ||
| 1335 | |||
| 1327 | pub const ThreadLocalMode = enum(c_uint) { | 1336 | pub const ThreadLocalMode = enum(c_uint) { |
| 1328 | NotThreadLocal, | 1337 | NotThreadLocal, |
| 1329 | GeneralDynamicTLSModel, | 1338 | GeneralDynamicTLSModel, |