authorgravatar for takeshi@tetrate.ioTakeshi Yoneda <takeshi@tetrate.io> 2021-09-24 22:14:53+09:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-10 15:21:48-07:00
log9654a54d4a2729200d38dbb6eec827cb03dc0f90
tree3b96d72cca0cb34c99f9a60f4b093e1fa4052dea
parent67c4b16d6e27f1d81e2e2f837bd53d958b9baa33

Add Visibility field to ExportOptions.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>

9 files changed, 95 insertions(+), 9 deletions(-)

lib/std/builtin.zig+9
......@@ -68,6 +68,14 @@ pub const GlobalLinkage = enum {
6868 LinkOnce,
6969};
7070
71/// This data structure is used by the Zig language code generation and
72/// therefore must be kept in sync with the compiler implementation.
73pub const GlobalVisibility = enum {
74 default,
75 hidden,
76 protected,
77};
78
7179/// This data structure is used by the Zig language code generation and
7280/// therefore must be kept in sync with the compiler implementation.
7381pub const AtomicOrder = enum {
......@@ -655,6 +663,7 @@ pub const ExportOptions = struct {
655663 name: []const u8,
656664 linkage: GlobalLinkage = .Strong,
657665 section: ?[]const u8 = null,
666 visibility: GlobalVisibility = .default,
658667};
659668
660669/// This data structure is used by the Zig language code generation and
src/Sema.zig+5
......@@ -4348,6 +4348,7 @@ pub fn analyzeExport(
43484348 .name = symbol_name,
43494349 .linkage = borrowed_options.linkage,
43504350 .section = section,
4351 .visibility = borrowed_options.visibility,
43514352 },
43524353 .src = src,
43534354 .link = switch (mod.comp.bin_file.tag) {
......@@ -15007,6 +15008,9 @@ fn resolveExportOptions(
1500715008 const section = try sema.fieldVal(block, src, options, "section", src);
1500815009 const section_val = try sema.resolveConstValue(block, src, section);
1500915010
15011 const visibility = try sema.fieldVal(block, src, options, "visibility", src);
15012 const visibility_val = try sema.resolveConstValue(block, src, visibility);
15013
1501015014 if (!section_val.isNull()) {
1501115015 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});
1501215016 }
......@@ -15015,6 +15019,7 @@ fn resolveExportOptions(
1501515019 .name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod),
1501615020 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
1501715021 .section = null, // TODO
15022 .visibility = visibility_val.toEnum(std.builtin.GlobalVisibility),
1501815023 };
1501915024}
1502015025
src/codegen/llvm.zig+5
......@@ -808,6 +808,11 @@ pub const Object = struct {
808808 .Weak => llvm_global.setLinkage(.WeakODR),
809809 .LinkOnce => llvm_global.setLinkage(.LinkOnceODR),
810810 }
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 }
811816 if (decl.val.castTag(.variable)) |variable| {
812817 if (variable.data.is_threadlocal) {
813818 llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);
src/codegen/llvm/bindings.zig+9
......@@ -117,6 +117,9 @@ pub const Value = opaque {
117117 pub const setLinkage = LLVMSetLinkage;
118118 extern fn LLVMSetLinkage(Global: *const Value, Linkage: Linkage) void;
119119
120 pub const setVisibility = LLVMSetVisibility;
121 extern fn LLVMSetVisibility(Global: *const Value, Linkage: Visibility) void;
122
120123 pub const setUnnamedAddr = LLVMSetUnnamedAddr;
121124 extern fn LLVMSetUnnamedAddr(Global: *const Value, HasUnnamedAddr: Bool) void;
122125
......@@ -1324,6 +1327,12 @@ pub const Linkage = enum(c_uint) {
13241327 LinkerPrivateWeak,
13251328};
13261329
1330pub const Visibility = enum(c_uint) {
1331 Default,
1332 Hidden,
1333 Protected,
1334};
1335
13271336pub const ThreadLocalMode = enum(c_uint) {
13281337 NotThreadLocal,
13291338 GeneralDynamicTLSModel,
src/stage1/all_types.hpp+7
......@@ -571,6 +571,12 @@ enum GlobalLinkageId {
571571 GlobalLinkageIdLinkOnce,
572572};
573573
574enum GlobalVisibilityId {
575 GlobalVisibilityIdDefault,
576 GlobalVisibilityIdHidden,
577 GlobalVisibilityIdProtected,
578};
579
574580enum TldId {
575581 TldIdVar,
576582 TldIdFn,
......@@ -1654,6 +1660,7 @@ enum FnAnalState {
16541660struct GlobalExport {
16551661 Buf name;
16561662 GlobalLinkageId linkage;
1663 GlobalVisibilityId visibility;
16571664};
16581665
16591666struct ZigFn {
src/stage1/analyze.cpp+7-5
......@@ -3717,14 +3717,15 @@ ZigType *get_test_fn_type(CodeGen *g) {
37173717 return g->test_fn_type;
37183718}
37193719
3720void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLinkageId linkage) {
3720void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility) {
37213721 GlobalExport *global_export = var->export_list.add_one();
37223722 memset(global_export, 0, sizeof(GlobalExport));
37233723 buf_init_from_str(&global_export->name, symbol_name);
37243724 global_export->linkage = linkage;
3725 global_export->visibility = visibility;
37253726}
37263727
3727void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc) {
3728void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility, CallingConvention cc) {
37283729 CallingConvention winapi_cc = g->zig_target->arch == ZigLLVM_x86
37293730 ? CallingConventionStdcall
37303731 : CallingConventionC;
......@@ -3749,6 +3750,7 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, G
37493750 memset(fn_export, 0, sizeof(GlobalExport));
37503751 buf_init_from_str(&fn_export->name, symbol_name);
37513752 fn_export->linkage = linkage;
3753 fn_export->visibility = visibility;
37523754}
37533755
37543756static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
......@@ -3852,13 +3854,13 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
38523854 case CallingConventionWin64:
38533855 case CallingConventionPtxKernel:
38543856 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3855 GlobalLinkageIdStrong, fn_cc);
3857 GlobalLinkageIdStrong, GlobalVisibilityIdDefault, fn_cc);
38563858 break;
38573859 case CallingConventionUnspecified:
38583860 // An exported function without a specific calling
38593861 // convention defaults to C
38603862 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3861 GlobalLinkageIdStrong, CallingConventionC);
3863 GlobalLinkageIdStrong, GlobalVisibilityIdDefault, CallingConventionC);
38623864 break;
38633865 }
38643866 }
......@@ -4321,7 +4323,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
43214323
43224324 if (is_export) {
43234325 validate_export_var_type(g, type, source_node);
4324 add_var_export(g, tld_var->var, tld_var->var->name, GlobalLinkageIdStrong);
4326 add_var_export(g, tld_var->var, tld_var->var->name, GlobalLinkageIdStrong, GlobalVisibilityIdDefault);
43254327 }
43264328
43274329 if (is_extern) {
src/stage1/analyze.hpp+2-2
......@@ -221,8 +221,8 @@ ZigType *get_align_amt_type(CodeGen *g);
221221ZigPackage *new_anonymous_package(void);
222222
223223Buf *const_value_to_buffer(ZigValue *const_val);
224void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc);
225void add_var_export(CodeGen *g, ZigVar *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage);
224void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility, CallingConvention cc);
225void add_var_export(CodeGen *g, ZigVar *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility);
226226
227227
228228ZigValue *get_builtin_value(CodeGen *codegen, const char *name);
src/stage1/codegen.cpp+20
......@@ -242,6 +242,18 @@ static LLVMLinkage to_llvm_linkage(GlobalLinkageId id, bool is_extern) {
242242 zig_unreachable();
243243}
244244
245static LLVMVisibility to_llvm_visibility(GlobalVisibilityId id) {
246 switch (id) {
247 case GlobalVisibilityIdDefault:
248 return LLVMDefaultVisibility;
249 case GlobalVisibilityIdHidden:
250 return LLVMHiddenVisibility;
251 case GlobalVisibilityIdProtected:
252 return LLVMProtectedVisibility;
253 }
254 zig_unreachable();
255}
256
245257struct CalcLLVMFieldIndex {
246258 uint32_t offset;
247259 uint32_t field_index;
......@@ -400,6 +412,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
400412 const char *unmangled_name = buf_ptr(&fn->symbol_name);
401413 const char *symbol_name;
402414 GlobalLinkageId linkage;
415 GlobalVisibilityId visibility = GlobalVisibilityIdDefault;
403416 if (fn->body_node == nullptr) {
404417 symbol_name = unmangled_name;
405418 linkage = GlobalLinkageIdStrong;
......@@ -410,6 +423,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
410423 GlobalExport *fn_export = &fn->export_list.items[0];
411424 symbol_name = buf_ptr(&fn_export->name);
412425 linkage = fn_export->linkage;
426 visibility = fn_export->visibility;
413427 }
414428
415429 CallingConvention cc = fn->type_entry->data.fn.fn_type_id.cc;
......@@ -532,6 +546,8 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
532546 LLVMSetUnnamedAddr(llvm_fn, true);
533547 }
534548
549 LLVMSetVisibility(llvm_fn, to_llvm_visibility(visibility));
550
535551 ZigType *return_type = fn_type->data.fn.fn_type_id.return_type;
536552 if (return_type->id == ZigTypeIdUnreachable) {
537553 addLLVMFnAttr(llvm_fn, "noreturn");
......@@ -8951,6 +8967,7 @@ static void do_code_gen(CodeGen *g) {
89518967 assert(var->decl_node);
89528968
89538969 GlobalLinkageId linkage;
8970 GlobalVisibilityId visibility = GlobalVisibilityIdDefault;
89548971 const char *unmangled_name = var->name;
89558972 const char *symbol_name;
89568973 if (var->export_list.length == 0) {
......@@ -8965,6 +8982,7 @@ static void do_code_gen(CodeGen *g) {
89658982 GlobalExport *global_export = &var->export_list.items[0];
89668983 symbol_name = buf_ptr(&global_export->name);
89678984 linkage = global_export->linkage;
8985 visibility = global_export->visibility;
89688986 }
89698987
89708988 LLVMValueRef global_value;
......@@ -9010,6 +9028,8 @@ static void do_code_gen(CodeGen *g) {
90109028 set_global_tls(g, var, global_value);
90119029 }
90129030
9031 LLVMSetVisibility(global_value, to_llvm_visibility(visibility));
9032
90139033 var->value_ref = global_value;
90149034
90159035 for (size_t export_i = 1; export_i < var->export_list.length; export_i += 1) {
src/stage1/ir.cpp+31-2
......@@ -8635,6 +8635,25 @@ static bool ir_resolve_global_linkage(IrAnalyze *ira, Stage1AirInst *value, Glob
86358635 return true;
86368636}
86378637
8638static bool ir_resolve_global_visibility(IrAnalyze *ira, Stage1AirInst *value, GlobalVisibilityId *out) {
8639 if (type_is_invalid(value->value->type))
8640 return false;
8641
8642 ZigType *global_visibility_type = get_builtin_type(ira->codegen, "GlobalVisibility");
8643
8644 Stage1AirInst *casted_value = ir_implicit_cast(ira, value, global_visibility_type);
8645 if (type_is_invalid(casted_value->value->type))
8646 return false;
8647
8648 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad);
8649 if (!const_val)
8650 return false;
8651
8652 *out = (GlobalVisibilityId)bigint_as_u32(&const_val->data.x_enum_tag);
8653 return true;
8654}
8655
8656
86388657static bool ir_resolve_float_mode(IrAnalyze *ira, Stage1AirInst *value, FloatMode *out) {
86398658 if (type_is_invalid(value->value->type))
86408659 return false;
......@@ -11661,6 +11680,12 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
1166111680 if (type_is_invalid(section_inst->value->type))
1166211681 return ira->codegen->invalid_inst_gen;
1166311682
11683 TypeStructField *visibility_field = find_struct_type_field(options_type, buf_create_from_str("visibility"));
11684 src_assert(visibility_field != nullptr, instruction->base.source_node);
11685 Stage1AirInst *visibility_inst = ir_analyze_struct_value_field_value(ira, instruction->base.scope, instruction->base.source_node, options, visibility_field);
11686 if (type_is_invalid(visibility_inst->value->type))
11687 return ira->codegen->invalid_inst_gen;
11688
1166411689 // The `section` field is optional, we have to unwrap it first
1166511690 Stage1AirInst *non_null_check = ir_analyze_test_non_null(ira, instruction->base.scope, instruction->base.source_node, section_inst);
1166611691 bool is_non_null;
......@@ -11689,6 +11714,10 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
1168911714 if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id))
1169011715 return ira->codegen->invalid_inst_gen;
1169111716
11717 GlobalVisibilityId global_visibility_id;
11718 if (!ir_resolve_global_visibility(ira, visibility_inst, &global_visibility_id))
11719 return ira->codegen->invalid_inst_gen;
11720
1169211721 Buf *section_name = nullptr;
1169311722 if (section_str_inst != nullptr && !(section_name = ir_resolve_str(ira, section_str_inst)))
1169411723 return ira->codegen->invalid_inst_gen;
......@@ -11751,7 +11780,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
1175111780 case CallingConventionSysV:
1175211781 case CallingConventionWin64:
1175311782 case CallingConventionPtxKernel:
11754 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc);
11783 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, global_visibility_id, cc);
1175511784 fn_entry->section_name = section_name;
1175611785 break;
1175711786 }
......@@ -11898,7 +11927,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
1189811927 if (load_ptr->ptr->id == Stage1AirInstIdVarPtr) {
1189911928 Stage1AirInstVarPtr *var_ptr = reinterpret_cast<Stage1AirInstVarPtr *>(load_ptr->ptr);
1190011929 ZigVar *var = var_ptr->var;
11901 add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id);
11930 add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id, global_visibility_id);
1190211931 var->section_name = section_name;
1190311932 }
1190411933 }