| author | |
| committer | |
| log | ee2575724597f214f8f4653f4a4ec1d2a6d97b8b |
| tree | 89eeba6c76af7e165937ff8f9ad34a65dfa9d470 |
| parent | 2d888a8e639856e8cb6e4c6f9e6a27647b464952 |
6 files changed, 45 insertions(+), 6 deletions(-)
lib/std/builtin.zig+9| ... | @@ -68,6 +68,14 @@ pub const GlobalLinkage = enum { | ... | @@ -68,6 +68,14 @@ pub const GlobalLinkage = enum { |
| 68 | link_once, | 68 | link_once, |
| 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 DllStorageClass = enum { | ||
| 74 | default, | ||
| 75 | import, | ||
| 76 | @"export", | ||
| 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 SymbolVisibility = enum { | 81 | pub const SymbolVisibility = enum { |
| ... | @@ -683,6 +691,7 @@ pub const ExternOptions = struct { | ... | @@ -683,6 +691,7 @@ pub const ExternOptions = struct { |
| 683 | library_name: ?[]const u8 = null, | 691 | library_name: ?[]const u8 = null, |
| 684 | linkage: GlobalLinkage = .strong, | 692 | linkage: GlobalLinkage = .strong, |
| 685 | is_thread_local: bool = false, | 693 | is_thread_local: bool = false, |
| 694 | dll_storage_class: DllStorageClass = .default, | ||
| 686 | }; | 695 | }; |
| 687 | 696 | ||
| 688 | /// This data structure is used by the Zig language code generation and | 697 | /// This data structure is used by the Zig language code generation and |
src/InternPool.zig+8-1| ... | @@ -2054,6 +2054,7 @@ pub const Key = union(enum) { | ... | @@ -2054,6 +2054,7 @@ pub const Key = union(enum) { |
| 2054 | is_const: bool, | 2054 | is_const: bool, |
| 2055 | is_threadlocal: bool, | 2055 | is_threadlocal: bool, |
| 2056 | is_weak_linkage: bool, | 2056 | is_weak_linkage: bool, |
| 2057 | is_dll_import: bool, | ||
| 2057 | alignment: Alignment, | 2058 | alignment: Alignment, |
| 2058 | @"addrspace": std.builtin.AddressSpace, | 2059 | @"addrspace": std.builtin.AddressSpace, |
| 2059 | /// The ZIR instruction which created this extern; used only for source locations. | 2060 | /// The ZIR instruction which created this extern; used only for source locations. |
| ... | @@ -2675,6 +2676,7 @@ pub const Key = union(enum) { | ... | @@ -2675,6 +2676,7 @@ pub const Key = union(enum) { |
| 2675 | asBytes(&e.ty) ++ asBytes(&e.lib_name) ++ | 2676 | asBytes(&e.ty) ++ asBytes(&e.lib_name) ++ |
| 2676 | asBytes(&e.is_const) ++ asBytes(&e.is_threadlocal) ++ | 2677 | asBytes(&e.is_const) ++ asBytes(&e.is_threadlocal) ++ |
| 2677 | asBytes(&e.is_weak_linkage) ++ asBytes(&e.alignment) ++ | 2678 | asBytes(&e.is_weak_linkage) ++ asBytes(&e.alignment) ++ |
| 2679 | asBytes(&e.is_dll_import) ++ asBytes(&e.alignment) ++ | ||
| 2678 | asBytes(&e.@"addrspace") ++ asBytes(&e.zir_index)), | 2680 | asBytes(&e.@"addrspace") ++ asBytes(&e.zir_index)), |
| 2679 | }; | 2681 | }; |
| 2680 | } | 2682 | } |
| ... | @@ -2771,6 +2773,7 @@ pub const Key = union(enum) { | ... | @@ -2771,6 +2773,7 @@ pub const Key = union(enum) { |
| 2771 | a_info.is_const == b_info.is_const and | 2773 | a_info.is_const == b_info.is_const and |
| 2772 | a_info.is_threadlocal == b_info.is_threadlocal and | 2774 | a_info.is_threadlocal == b_info.is_threadlocal and |
| 2773 | a_info.is_weak_linkage == b_info.is_weak_linkage and | 2775 | a_info.is_weak_linkage == b_info.is_weak_linkage and |
| 2776 | a_info.is_dll_import == b_info.is_dll_import and | ||
| 2774 | a_info.alignment == b_info.alignment and | 2777 | a_info.alignment == b_info.alignment and |
| 2775 | a_info.@"addrspace" == b_info.@"addrspace" and | 2778 | a_info.@"addrspace" == b_info.@"addrspace" and |
| 2776 | a_info.zir_index == b_info.zir_index; | 2779 | a_info.zir_index == b_info.zir_index; |
| ... | @@ -5370,7 +5373,8 @@ pub const Tag = enum(u8) { | ... | @@ -5370,7 +5373,8 @@ pub const Tag = enum(u8) { |
| 5370 | is_const: bool, | 5373 | is_const: bool, |
| 5371 | is_threadlocal: bool, | 5374 | is_threadlocal: bool, |
| 5372 | is_weak_linkage: bool, | 5375 | is_weak_linkage: bool, |
| 5373 | _: u29 = 0, | 5376 | is_dll_import: bool, |
| 5377 | _: u28 = 0, | ||
| 5374 | }; | 5378 | }; |
| 5375 | }; | 5379 | }; |
| 5376 | 5380 | ||
| ... | @@ -6715,6 +6719,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -6715,6 +6719,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6715 | .is_const = extra.flags.is_const, | 6719 | .is_const = extra.flags.is_const, |
| 6716 | .is_threadlocal = extra.flags.is_threadlocal, | 6720 | .is_threadlocal = extra.flags.is_threadlocal, |
| 6717 | .is_weak_linkage = extra.flags.is_weak_linkage, | 6721 | .is_weak_linkage = extra.flags.is_weak_linkage, |
| 6722 | .is_dll_import = extra.flags.is_dll_import, | ||
| 6718 | .alignment = nav.status.resolved.alignment, | 6723 | .alignment = nav.status.resolved.alignment, |
| 6719 | .@"addrspace" = nav.status.resolved.@"addrspace", | 6724 | .@"addrspace" = nav.status.resolved.@"addrspace", |
| 6720 | .zir_index = extra.zir_index, | 6725 | .zir_index = extra.zir_index, |
| ... | @@ -7381,6 +7386,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All | ... | @@ -7381,6 +7386,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 7381 | .is_const = false, | 7386 | .is_const = false, |
| 7382 | .is_threadlocal = variable.is_threadlocal, | 7387 | .is_threadlocal = variable.is_threadlocal, |
| 7383 | .is_weak_linkage = variable.is_weak_linkage, | 7388 | .is_weak_linkage = variable.is_weak_linkage, |
| 7389 | .is_dll_import = false, | ||
| 7384 | }, | 7390 | }, |
| 7385 | }), | 7391 | }), |
| 7386 | }); | 7392 | }); |
| ... | @@ -8644,6 +8650,7 @@ pub fn getExtern( | ... | @@ -8644,6 +8650,7 @@ pub fn getExtern( |
| 8644 | .is_const = key.is_const, | 8650 | .is_const = key.is_const, |
| 8645 | .is_threadlocal = key.is_threadlocal, | 8651 | .is_threadlocal = key.is_threadlocal, |
| 8646 | .is_weak_linkage = key.is_weak_linkage, | 8652 | .is_weak_linkage = key.is_weak_linkage, |
| 8653 | .is_dll_import = key.is_dll_import, | ||
| 8647 | }, | 8654 | }, |
| 8648 | .zir_index = key.zir_index, | 8655 | .zir_index = key.zir_index, |
| 8649 | .owner_nav = owner_nav, | 8656 | .owner_nav = owner_nav, |
src/Sema.zig+16| ... | @@ -9960,6 +9960,7 @@ fn funcCommon( | ... | @@ -9960,6 +9960,7 @@ fn funcCommon( |
| 9960 | .is_const = true, | 9960 | .is_const = true, |
| 9961 | .is_threadlocal = false, | 9961 | .is_threadlocal = false, |
| 9962 | .is_weak_linkage = false, | 9962 | .is_weak_linkage = false, |
| 9963 | .is_dll_import = false, | ||
| 9963 | .alignment = alignment orelse .none, | 9964 | .alignment = alignment orelse .none, |
| 9964 | .@"addrspace" = address_space orelse .generic, | 9965 | .@"addrspace" = address_space orelse .generic, |
| 9965 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction | 9966 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction |
| ... | @@ -26505,6 +26506,7 @@ fn zirVarExtended( | ... | @@ -26505,6 +26506,7 @@ fn zirVarExtended( |
| 26505 | .is_const = small.is_const, | 26506 | .is_const = small.is_const, |
| 26506 | .is_threadlocal = small.is_threadlocal, | 26507 | .is_threadlocal = small.is_threadlocal, |
| 26507 | .is_weak_linkage = false, | 26508 | .is_weak_linkage = false, |
| 26509 | .is_dll_import = false, | ||
| 26508 | .alignment = alignment, | 26510 | .alignment = alignment, |
| 26509 | .@"addrspace" = @"addrspace", | 26511 | .@"addrspace" = @"addrspace", |
| 26510 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction | 26512 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction |
| ... | @@ -26958,6 +26960,7 @@ fn resolveExternOptions( | ... | @@ -26958,6 +26960,7 @@ fn resolveExternOptions( |
| 26958 | library_name: InternPool.OptionalNullTerminatedString = .none, | 26960 | library_name: InternPool.OptionalNullTerminatedString = .none, |
| 26959 | linkage: std.builtin.GlobalLinkage = .strong, | 26961 | linkage: std.builtin.GlobalLinkage = .strong, |
| 26960 | is_thread_local: bool = false, | 26962 | is_thread_local: bool = false, |
| 26963 | dll_storage_class: std.builtin.DllStorageClass = .default, | ||
| 26961 | } { | 26964 | } { |
| 26962 | const pt = sema.pt; | 26965 | const pt = sema.pt; |
| 26963 | const zcu = pt.zcu; | 26966 | const zcu = pt.zcu; |
| ... | @@ -26971,6 +26974,7 @@ fn resolveExternOptions( | ... | @@ -26971,6 +26974,7 @@ fn resolveExternOptions( |
| 26971 | const library_src = block.src(.{ .init_field_library = src.offset.node_offset_builtin_call_arg.builtin_call_node }); | 26974 | const library_src = block.src(.{ .init_field_library = src.offset.node_offset_builtin_call_arg.builtin_call_node }); |
| 26972 | const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node }); | 26975 | const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node }); |
| 26973 | const thread_local_src = block.src(.{ .init_field_thread_local = src.offset.node_offset_builtin_call_arg.builtin_call_node }); | 26976 | const thread_local_src = block.src(.{ .init_field_thread_local = src.offset.node_offset_builtin_call_arg.builtin_call_node }); |
| 26977 | const dll_storage_class_src = block.src(.{ .init_field_dll_storage_class = src.offset.node_offset_builtin_call_arg.builtin_call_node }); | ||
| 26974 | 26978 | ||
| 26975 | const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src); | 26979 | const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src); |
| 26976 | const name = try sema.toConstString(block, name_src, name_ref, .{ | 26980 | const name = try sema.toConstString(block, name_src, name_ref, .{ |
| ... | @@ -27004,6 +27008,12 @@ fn resolveExternOptions( | ... | @@ -27004,6 +27008,12 @@ fn resolveExternOptions( |
| 27004 | break :library_name library_name; | 27008 | break :library_name library_name; |
| 27005 | } else null; | 27009 | } else null; |
| 27006 | 27010 | ||
| 27011 | const dll_storage_class_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "dll_storage_class", .no_embedded_nulls), dll_storage_class_src); | ||
| 27012 | const dll_storage_class_val = try sema.resolveConstDefinedValue(block, dll_storage_class_src, dll_storage_class_ref, .{ | ||
| 27013 | .needed_comptime_reason = "dll_storage_class of the extern symbol must be comptime-known", | ||
| 27014 | }); | ||
| 27015 | const dll_storage_class = zcu.toEnum(std.builtin.DllStorageClass, dll_storage_class_val); | ||
| 27016 | |||
| 27007 | if (name.len == 0) { | 27017 | if (name.len == 0) { |
| 27008 | return sema.fail(block, name_src, "extern symbol name cannot be empty", .{}); | 27018 | return sema.fail(block, name_src, "extern symbol name cannot be empty", .{}); |
| 27009 | } | 27019 | } |
| ... | @@ -27012,11 +27022,16 @@ fn resolveExternOptions( | ... | @@ -27012,11 +27022,16 @@ fn resolveExternOptions( |
| 27012 | return sema.fail(block, linkage_src, "extern symbol must use strong or weak linkage", .{}); | 27022 | return sema.fail(block, linkage_src, "extern symbol must use strong or weak linkage", .{}); |
| 27013 | } | 27023 | } |
| 27014 | 27024 | ||
| 27025 | if (dll_storage_class == .@"export") { | ||
| 27026 | return sema.fail(block, dll_storage_class_src, "extern symbol cannot have export dll storage class", .{}); | ||
| 27027 | } | ||
| 27028 | |||
| 27015 | return .{ | 27029 | return .{ |
| 27016 | .name = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls), | 27030 | .name = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls), |
| 27017 | .library_name = try ip.getOrPutStringOpt(gpa, pt.tid, library_name, .no_embedded_nulls), | 27031 | .library_name = try ip.getOrPutStringOpt(gpa, pt.tid, library_name, .no_embedded_nulls), |
| 27018 | .linkage = linkage, | 27032 | .linkage = linkage, |
| 27019 | .is_thread_local = is_thread_local_val.toBool(), | 27033 | .is_thread_local = is_thread_local_val.toBool(), |
| 27034 | .dll_storage_class = dll_storage_class, | ||
| 27020 | }; | 27035 | }; |
| 27021 | } | 27036 | } |
| 27022 | 27037 | ||
| ... | @@ -27062,6 +27077,7 @@ fn zirBuiltinExtern( | ... | @@ -27062,6 +27077,7 @@ fn zirBuiltinExtern( |
| 27062 | .is_const = ptr_info.flags.is_const, | 27077 | .is_const = ptr_info.flags.is_const, |
| 27063 | .is_threadlocal = options.is_thread_local, | 27078 | .is_threadlocal = options.is_thread_local, |
| 27064 | .is_weak_linkage = options.linkage == .weak, | 27079 | .is_weak_linkage = options.linkage == .weak, |
| 27080 | .is_dll_import = options.dll_storage_class == .import, | ||
| 27065 | .alignment = ptr_info.flags.alignment, | 27081 | .alignment = ptr_info.flags.alignment, |
| 27066 | .@"addrspace" = ptr_info.flags.address_space, | 27082 | .@"addrspace" = ptr_info.flags.address_space, |
| 27067 | // This instruction is just for source locations. | 27083 | // This instruction is just for source locations. |
src/Zcu.zig+3| ... | @@ -1522,6 +1522,7 @@ pub const SrcLoc = struct { | ... | @@ -1522,6 +1522,7 @@ pub const SrcLoc = struct { |
| 1522 | .init_field_cache, | 1522 | .init_field_cache, |
| 1523 | .init_field_library, | 1523 | .init_field_library, |
| 1524 | .init_field_thread_local, | 1524 | .init_field_thread_local, |
| 1525 | .init_field_dll_storage_class, | ||
| 1525 | => |builtin_call_node| { | 1526 | => |builtin_call_node| { |
| 1526 | const wanted = switch (src_loc.lazy) { | 1527 | const wanted = switch (src_loc.lazy) { |
| 1527 | .init_field_name => "name", | 1528 | .init_field_name => "name", |
| ... | @@ -1533,6 +1534,7 @@ pub const SrcLoc = struct { | ... | @@ -1533,6 +1534,7 @@ pub const SrcLoc = struct { |
| 1533 | .init_field_cache => "cache", | 1534 | .init_field_cache => "cache", |
| 1534 | .init_field_library => "library", | 1535 | .init_field_library => "library", |
| 1535 | .init_field_thread_local => "thread_local", | 1536 | .init_field_thread_local => "thread_local", |
| 1537 | .init_field_dll_storage_class => "dll_storage_class", | ||
| 1536 | else => unreachable, | 1538 | else => unreachable, |
| 1537 | }; | 1539 | }; |
| 1538 | const tree = try src_loc.file_scope.getTree(gpa); | 1540 | const tree = try src_loc.file_scope.getTree(gpa); |
| ... | @@ -1959,6 +1961,7 @@ pub const LazySrcLoc = struct { | ... | @@ -1959,6 +1961,7 @@ pub const LazySrcLoc = struct { |
| 1959 | init_field_cache: i32, | 1961 | init_field_cache: i32, |
| 1960 | init_field_library: i32, | 1962 | init_field_library: i32, |
| 1961 | init_field_thread_local: i32, | 1963 | init_field_thread_local: i32, |
| 1964 | init_field_dll_storage_class: i32, | ||
| 1962 | /// The source location points to the value of an item in a specific | 1965 | /// The source location points to the value of an item in a specific |
| 1963 | /// case of a `switch`. | 1966 | /// case of a `switch`. |
| 1964 | switch_case_item: SwitchItem, | 1967 | switch_case_item: SwitchItem, |
src/Zcu/PerThread.zig+1| ... | @@ -2763,6 +2763,7 @@ pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!V | ... | @@ -2763,6 +2763,7 @@ pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!V |
| 2763 | .is_const = e.is_const, | 2763 | .is_const = e.is_const, |
| 2764 | .is_threadlocal = e.is_threadlocal, | 2764 | .is_threadlocal = e.is_threadlocal, |
| 2765 | .is_weak_linkage = e.is_weak_linkage, | 2765 | .is_weak_linkage = e.is_weak_linkage, |
| 2766 | .is_dll_import = e.is_dll_import, | ||
| 2766 | .alignment = e.alignment, | 2767 | .alignment = e.alignment, |
| 2767 | .@"addrspace" = e.@"addrspace", | 2768 | .@"addrspace" = e.@"addrspace", |
| 2768 | .zir_index = e.zir_index, | 2769 | .zir_index = e.zir_index, |
src/codegen/llvm.zig+8-5| ... | @@ -4782,10 +4782,10 @@ pub const NavGen = struct { | ... | @@ -4782,10 +4782,10 @@ pub const NavGen = struct { |
| 4782 | const nav = ip.getNav(nav_index); | 4782 | const nav = ip.getNav(nav_index); |
| 4783 | const resolved = nav.status.resolved; | 4783 | const resolved = nav.status.resolved; |
| 4784 | 4784 | ||
| 4785 | const is_extern, const lib_name, const is_threadlocal, const is_weak_linkage, const is_const, const init_val, const owner_nav = switch (ip.indexToKey(resolved.val)) { | 4785 | const is_extern, const lib_name, const is_threadlocal, const is_weak_linkage, const is_dll_import, const is_const, const init_val, const owner_nav = switch (ip.indexToKey(resolved.val)) { |
| 4786 | .variable => |variable| .{ false, variable.lib_name, variable.is_threadlocal, variable.is_weak_linkage, false, variable.init, variable.owner_nav }, | 4786 | .variable => |variable| .{ false, variable.lib_name, variable.is_threadlocal, variable.is_weak_linkage, false, false, variable.init, variable.owner_nav }, |
| 4787 | .@"extern" => |@"extern"| .{ true, @"extern".lib_name, @"extern".is_threadlocal, @"extern".is_weak_linkage, @"extern".is_const, .none, @"extern".owner_nav }, | 4787 | .@"extern" => |@"extern"| .{ true, @"extern".lib_name, @"extern".is_threadlocal, @"extern".is_weak_linkage, @"extern".is_dll_import, @"extern".is_const, .none, @"extern".owner_nav }, |
| 4788 | else => .{ false, .none, false, false, true, resolved.val, nav_index }, | 4788 | else => .{ false, .none, false, false, false, true, resolved.val, nav_index }, |
| 4789 | }; | 4789 | }; |
| 4790 | const ty = Type.fromInterned(nav.typeOf(ip)); | 4790 | const ty = Type.fromInterned(nav.typeOf(ip)); |
| 4791 | 4791 | ||
| ... | @@ -4860,8 +4860,11 @@ pub const NavGen = struct { | ... | @@ -4860,8 +4860,11 @@ pub const NavGen = struct { |
| 4860 | try global_index.rename(decl_name, &o.builder); | 4860 | try global_index.rename(decl_name, &o.builder); |
| 4861 | global_index.setLinkage(.external, &o.builder); | 4861 | global_index.setLinkage(.external, &o.builder); |
| 4862 | global_index.setUnnamedAddr(.default, &o.builder); | 4862 | global_index.setUnnamedAddr(.default, &o.builder); |
| 4863 | if (zcu.comp.config.dll_export_fns) | 4863 | if (is_dll_import) { |
| 4864 | global_index.setDllStorageClass(.dllimport, &o.builder); | ||
| 4865 | } else if (zcu.comp.config.dll_export_fns) { | ||
| 4864 | global_index.setDllStorageClass(.default, &o.builder); | 4866 | global_index.setDllStorageClass(.default, &o.builder); |
| 4867 | } | ||
| 4865 | 4868 | ||
| 4866 | if (is_weak_linkage) global_index.setLinkage(.extern_weak, &o.builder); | 4869 | if (is_weak_linkage) global_index.setLinkage(.extern_weak, &o.builder); |
| 4867 | } | 4870 | } |