| author | |
| committer | |
| log | 9654a54d4a2729200d38dbb6eec827cb03dc0f90 |
| tree | 3b96d72cca0cb34c99f9a60f4b093e1fa4052dea |
| parent | 67c4b16d6e27f1d81e2e2f837bd53d958b9baa33 |
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 { | ... | @@ -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 GlobalVisibility = 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: GlobalVisibility = .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+5| ... | @@ -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) { |
| ... | @@ -15007,6 +15008,9 @@ fn resolveExportOptions( | ... | @@ -15007,6 +15008,9 @@ fn resolveExportOptions( |
| 15007 | const section = try sema.fieldVal(block, src, options, "section", src); | 15008 | const section = try sema.fieldVal(block, src, options, "section", src); |
| 15008 | const section_val = try sema.resolveConstValue(block, src, section); | 15009 | const section_val = try sema.resolveConstValue(block, src, section); |
| 15009 | 15010 | ||
| 15011 | const visibility = try sema.fieldVal(block, src, options, "visibility", src); | ||
| 15012 | const visibility_val = try sema.resolveConstValue(block, src, visibility); | ||
| 15013 | |||
| 15010 | if (!section_val.isNull()) { | 15014 | if (!section_val.isNull()) { |
| 15011 | return sema.fail(block, src, "TODO: implement exporting with linksection", .{}); | 15015 | return sema.fail(block, src, "TODO: implement exporting with linksection", .{}); |
| 15012 | } | 15016 | } |
| ... | @@ -15015,6 +15019,7 @@ fn resolveExportOptions( | ... | @@ -15015,6 +15019,7 @@ fn resolveExportOptions( |
| 15015 | .name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod), | 15019 | .name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod), |
| 15016 | .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage), | 15020 | .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage), |
| 15017 | .section = null, // TODO | 15021 | .section = null, // TODO |
| 15022 | .visibility = visibility_val.toEnum(std.builtin.GlobalVisibility), | ||
| 15018 | }; | 15023 | }; |
| 15019 | } | 15024 | } |
| 15020 | 15025 |
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, |
src/stage1/all_types.hpp+7| ... | @@ -571,6 +571,12 @@ enum GlobalLinkageId { | ... | @@ -571,6 +571,12 @@ enum GlobalLinkageId { |
| 571 | GlobalLinkageIdLinkOnce, | 571 | GlobalLinkageIdLinkOnce, |
| 572 | }; | 572 | }; |
| 573 | 573 | ||
| 574 | enum GlobalVisibilityId { | ||
| 575 | GlobalVisibilityIdDefault, | ||
| 576 | GlobalVisibilityIdHidden, | ||
| 577 | GlobalVisibilityIdProtected, | ||
| 578 | }; | ||
| 579 | |||
| 574 | enum TldId { | 580 | enum TldId { |
| 575 | TldIdVar, | 581 | TldIdVar, |
| 576 | TldIdFn, | 582 | TldIdFn, |
| ... | @@ -1654,6 +1660,7 @@ enum FnAnalState { | ... | @@ -1654,6 +1660,7 @@ enum FnAnalState { |
| 1654 | struct GlobalExport { | 1660 | struct GlobalExport { |
| 1655 | Buf name; | 1661 | Buf name; |
| 1656 | GlobalLinkageId linkage; | 1662 | GlobalLinkageId linkage; |
| 1663 | GlobalVisibilityId visibility; | ||
| 1657 | }; | 1664 | }; |
| 1658 | 1665 | ||
| 1659 | struct ZigFn { | 1666 | struct ZigFn { |
src/stage1/analyze.cpp+7-5| ... | @@ -3717,14 +3717,15 @@ ZigType *get_test_fn_type(CodeGen *g) { | ... | @@ -3717,14 +3717,15 @@ ZigType *get_test_fn_type(CodeGen *g) { |
| 3717 | return g->test_fn_type; | 3717 | return g->test_fn_type; |
| 3718 | } | 3718 | } |
| 3719 | 3719 | ||
| 3720 | void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLinkageId linkage) { | 3720 | void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility) { |
| 3721 | GlobalExport *global_export = var->export_list.add_one(); | 3721 | GlobalExport *global_export = var->export_list.add_one(); |
| 3722 | memset(global_export, 0, sizeof(GlobalExport)); | 3722 | memset(global_export, 0, sizeof(GlobalExport)); |
| 3723 | buf_init_from_str(&global_export->name, symbol_name); | 3723 | buf_init_from_str(&global_export->name, symbol_name); |
| 3724 | global_export->linkage = linkage; | 3724 | global_export->linkage = linkage; |
| 3725 | global_export->visibility = visibility; | ||
| 3725 | } | 3726 | } |
| 3726 | 3727 | ||
| 3727 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc) { | 3728 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility, CallingConvention cc) { |
| 3728 | CallingConvention winapi_cc = g->zig_target->arch == ZigLLVM_x86 | 3729 | CallingConvention winapi_cc = g->zig_target->arch == ZigLLVM_x86 |
| 3729 | ? CallingConventionStdcall | 3730 | ? CallingConventionStdcall |
| 3730 | : CallingConventionC; | 3731 | : CallingConventionC; |
| ... | @@ -3749,6 +3750,7 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, G | ... | @@ -3749,6 +3750,7 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, G |
| 3749 | memset(fn_export, 0, sizeof(GlobalExport)); | 3750 | memset(fn_export, 0, sizeof(GlobalExport)); |
| 3750 | buf_init_from_str(&fn_export->name, symbol_name); | 3751 | buf_init_from_str(&fn_export->name, symbol_name); |
| 3751 | fn_export->linkage = linkage; | 3752 | fn_export->linkage = linkage; |
| 3753 | fn_export->visibility = visibility; | ||
| 3752 | } | 3754 | } |
| 3753 | 3755 | ||
| 3754 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | 3756 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| ... | @@ -3852,13 +3854,13 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -3852,13 +3854,13 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 3852 | case CallingConventionWin64: | 3854 | case CallingConventionWin64: |
| 3853 | case CallingConventionPtxKernel: | 3855 | case CallingConventionPtxKernel: |
| 3854 | add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), | 3856 | add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), |
| 3855 | GlobalLinkageIdStrong, fn_cc); | 3857 | GlobalLinkageIdStrong, GlobalVisibilityIdDefault, fn_cc); |
| 3856 | break; | 3858 | break; |
| 3857 | case CallingConventionUnspecified: | 3859 | case CallingConventionUnspecified: |
| 3858 | // An exported function without a specific calling | 3860 | // An exported function without a specific calling |
| 3859 | // convention defaults to C | 3861 | // convention defaults to C |
| 3860 | add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), | 3862 | add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), |
| 3861 | GlobalLinkageIdStrong, CallingConventionC); | 3863 | GlobalLinkageIdStrong, GlobalVisibilityIdDefault, CallingConventionC); |
| 3862 | break; | 3864 | break; |
| 3863 | } | 3865 | } |
| 3864 | } | 3866 | } |
| ... | @@ -4321,7 +4323,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { | ... | @@ -4321,7 +4323,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { |
| 4321 | 4323 | ||
| 4322 | if (is_export) { | 4324 | if (is_export) { |
| 4323 | validate_export_var_type(g, type, source_node); | 4325 | 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); |
| 4325 | } | 4327 | } |
| 4326 | 4328 | ||
| 4327 | if (is_extern) { | 4329 | if (is_extern) { |
src/stage1/analyze.hpp+2-2| ... | @@ -221,8 +221,8 @@ ZigType *get_align_amt_type(CodeGen *g); | ... | @@ -221,8 +221,8 @@ ZigType *get_align_amt_type(CodeGen *g); |
| 221 | ZigPackage *new_anonymous_package(void); | 221 | ZigPackage *new_anonymous_package(void); |
| 222 | 222 | ||
| 223 | Buf *const_value_to_buffer(ZigValue *const_val); | 223 | Buf *const_value_to_buffer(ZigValue *const_val); |
| 224 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc); | 224 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility, CallingConvention cc); |
| 225 | void add_var_export(CodeGen *g, ZigVar *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage); | 225 | void add_var_export(CodeGen *g, ZigVar *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility); |
| 226 | 226 | ||
| 227 | 227 | ||
| 228 | ZigValue *get_builtin_value(CodeGen *codegen, const char *name); | 228 | ZigValue *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) { | ... | @@ -242,6 +242,18 @@ static LLVMLinkage to_llvm_linkage(GlobalLinkageId id, bool is_extern) { |
| 242 | zig_unreachable(); | 242 | zig_unreachable(); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | static 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 | |||
| 245 | struct CalcLLVMFieldIndex { | 257 | struct CalcLLVMFieldIndex { |
| 246 | uint32_t offset; | 258 | uint32_t offset; |
| 247 | uint32_t field_index; | 259 | uint32_t field_index; |
| ... | @@ -400,6 +412,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { | ... | @@ -400,6 +412,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { |
| 400 | const char *unmangled_name = buf_ptr(&fn->symbol_name); | 412 | const char *unmangled_name = buf_ptr(&fn->symbol_name); |
| 401 | const char *symbol_name; | 413 | const char *symbol_name; |
| 402 | GlobalLinkageId linkage; | 414 | GlobalLinkageId linkage; |
| 415 | GlobalVisibilityId visibility = GlobalVisibilityIdDefault; | ||
| 403 | if (fn->body_node == nullptr) { | 416 | if (fn->body_node == nullptr) { |
| 404 | symbol_name = unmangled_name; | 417 | symbol_name = unmangled_name; |
| 405 | linkage = GlobalLinkageIdStrong; | 418 | linkage = GlobalLinkageIdStrong; |
| ... | @@ -410,6 +423,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { | ... | @@ -410,6 +423,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { |
| 410 | GlobalExport *fn_export = &fn->export_list.items[0]; | 423 | GlobalExport *fn_export = &fn->export_list.items[0]; |
| 411 | symbol_name = buf_ptr(&fn_export->name); | 424 | symbol_name = buf_ptr(&fn_export->name); |
| 412 | linkage = fn_export->linkage; | 425 | linkage = fn_export->linkage; |
| 426 | visibility = fn_export->visibility; | ||
| 413 | } | 427 | } |
| 414 | 428 | ||
| 415 | CallingConvention cc = fn->type_entry->data.fn.fn_type_id.cc; | 429 | 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) { | ... | @@ -532,6 +546,8 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { |
| 532 | LLVMSetUnnamedAddr(llvm_fn, true); | 546 | LLVMSetUnnamedAddr(llvm_fn, true); |
| 533 | } | 547 | } |
| 534 | 548 | ||
| 549 | LLVMSetVisibility(llvm_fn, to_llvm_visibility(visibility)); | ||
| 550 | |||
| 535 | ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; | 551 | ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; |
| 536 | if (return_type->id == ZigTypeIdUnreachable) { | 552 | if (return_type->id == ZigTypeIdUnreachable) { |
| 537 | addLLVMFnAttr(llvm_fn, "noreturn"); | 553 | addLLVMFnAttr(llvm_fn, "noreturn"); |
| ... | @@ -8951,6 +8967,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -8951,6 +8967,7 @@ static void do_code_gen(CodeGen *g) { |
| 8951 | assert(var->decl_node); | 8967 | assert(var->decl_node); |
| 8952 | 8968 | ||
| 8953 | GlobalLinkageId linkage; | 8969 | GlobalLinkageId linkage; |
| 8970 | GlobalVisibilityId visibility = GlobalVisibilityIdDefault; | ||
| 8954 | const char *unmangled_name = var->name; | 8971 | const char *unmangled_name = var->name; |
| 8955 | const char *symbol_name; | 8972 | const char *symbol_name; |
| 8956 | if (var->export_list.length == 0) { | 8973 | if (var->export_list.length == 0) { |
| ... | @@ -8965,6 +8982,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -8965,6 +8982,7 @@ static void do_code_gen(CodeGen *g) { |
| 8965 | GlobalExport *global_export = &var->export_list.items[0]; | 8982 | GlobalExport *global_export = &var->export_list.items[0]; |
| 8966 | symbol_name = buf_ptr(&global_export->name); | 8983 | symbol_name = buf_ptr(&global_export->name); |
| 8967 | linkage = global_export->linkage; | 8984 | linkage = global_export->linkage; |
| 8985 | visibility = global_export->visibility; | ||
| 8968 | } | 8986 | } |
| 8969 | 8987 | ||
| 8970 | LLVMValueRef global_value; | 8988 | LLVMValueRef global_value; |
| ... | @@ -9010,6 +9028,8 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -9010,6 +9028,8 @@ static void do_code_gen(CodeGen *g) { |
| 9010 | set_global_tls(g, var, global_value); | 9028 | set_global_tls(g, var, global_value); |
| 9011 | } | 9029 | } |
| 9012 | 9030 | ||
| 9031 | LLVMSetVisibility(global_value, to_llvm_visibility(visibility)); | ||
| 9032 | |||
| 9013 | var->value_ref = global_value; | 9033 | var->value_ref = global_value; |
| 9014 | 9034 | ||
| 9015 | for (size_t export_i = 1; export_i < var->export_list.length; export_i += 1) { | 9035 | 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 | ... | @@ -8635,6 +8635,25 @@ static bool ir_resolve_global_linkage(IrAnalyze *ira, Stage1AirInst *value, Glob |
| 8635 | return true; | 8635 | return true; |
| 8636 | } | 8636 | } |
| 8637 | 8637 | ||
| 8638 | static 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 | |||
| 8638 | static bool ir_resolve_float_mode(IrAnalyze *ira, Stage1AirInst *value, FloatMode *out) { | 8657 | static bool ir_resolve_float_mode(IrAnalyze *ira, Stage1AirInst *value, FloatMode *out) { |
| 8639 | if (type_is_invalid(value->value->type)) | 8658 | if (type_is_invalid(value->value->type)) |
| 8640 | return false; | 8659 | return false; |
| ... | @@ -11661,6 +11680,12 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns | ... | @@ -11661,6 +11680,12 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns |
| 11661 | if (type_is_invalid(section_inst->value->type)) | 11680 | if (type_is_invalid(section_inst->value->type)) |
| 11662 | return ira->codegen->invalid_inst_gen; | 11681 | return ira->codegen->invalid_inst_gen; |
| 11663 | 11682 | ||
| 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 | |||
| 11664 | // The `section` field is optional, we have to unwrap it first | 11689 | // The `section` field is optional, we have to unwrap it first |
| 11665 | Stage1AirInst *non_null_check = ir_analyze_test_non_null(ira, instruction->base.scope, instruction->base.source_node, section_inst); | 11690 | Stage1AirInst *non_null_check = ir_analyze_test_non_null(ira, instruction->base.scope, instruction->base.source_node, section_inst); |
| 11666 | bool is_non_null; | 11691 | bool is_non_null; |
| ... | @@ -11689,6 +11714,10 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns | ... | @@ -11689,6 +11714,10 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns |
| 11689 | if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id)) | 11714 | if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id)) |
| 11690 | return ira->codegen->invalid_inst_gen; | 11715 | return ira->codegen->invalid_inst_gen; |
| 11691 | 11716 | ||
| 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 | |||
| 11692 | Buf *section_name = nullptr; | 11721 | Buf *section_name = nullptr; |
| 11693 | if (section_str_inst != nullptr && !(section_name = ir_resolve_str(ira, section_str_inst))) | 11722 | if (section_str_inst != nullptr && !(section_name = ir_resolve_str(ira, section_str_inst))) |
| 11694 | return ira->codegen->invalid_inst_gen; | 11723 | return ira->codegen->invalid_inst_gen; |
| ... | @@ -11751,7 +11780,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns | ... | @@ -11751,7 +11780,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns |
| 11751 | case CallingConventionSysV: | 11780 | case CallingConventionSysV: |
| 11752 | case CallingConventionWin64: | 11781 | case CallingConventionWin64: |
| 11753 | case CallingConventionPtxKernel: | 11782 | 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); |
| 11755 | fn_entry->section_name = section_name; | 11784 | fn_entry->section_name = section_name; |
| 11756 | break; | 11785 | break; |
| 11757 | } | 11786 | } |
| ... | @@ -11898,7 +11927,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns | ... | @@ -11898,7 +11927,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns |
| 11898 | if (load_ptr->ptr->id == Stage1AirInstIdVarPtr) { | 11927 | if (load_ptr->ptr->id == Stage1AirInstIdVarPtr) { |
| 11899 | Stage1AirInstVarPtr *var_ptr = reinterpret_cast<Stage1AirInstVarPtr *>(load_ptr->ptr); | 11928 | Stage1AirInstVarPtr *var_ptr = reinterpret_cast<Stage1AirInstVarPtr *>(load_ptr->ptr); |
| 11900 | ZigVar *var = var_ptr->var; | 11929 | 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); |
| 11902 | var->section_name = section_name; | 11931 | var->section_name = section_name; |
| 11903 | } | 11932 | } |
| 11904 | } | 11933 | } |