authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2024-10-19 18:15:39-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2024-10-22 12:41:35-04:00
logee2575724597f214f8f4653f4a4ec1d2a6d97b8b
tree89eeba6c76af7e165937ff8f9ad34a65dfa9d470
parent2d888a8e639856e8cb6e4c6f9e6a27647b464952

Add support for specifying `dll_storage_class` in @extern


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};
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 DllStorageClass = enum {
74 default,
75 import,
76 @"export",
77};
78
71/// This data structure is used by the Zig language code generation and79/// 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.
73pub const SymbolVisibility = enum {81pub 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};
687696
688/// This data structure is used by the Zig language code generation and697/// 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 and2773 a_info.is_const == b_info.is_const and
2772 a_info.is_threadlocal == b_info.is_threadlocal and2774 a_info.is_threadlocal == b_info.is_threadlocal and
2773 a_info.is_weak_linkage == b_info.is_weak_linkage and2775 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 and2777 a_info.alignment == b_info.alignment and
2775 a_info.@"addrspace" == b_info.@"addrspace" and2778 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 };
53765380
...@@ -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` instruction9966 .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` instruction26512 .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 });
2697426978
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;
2700627010
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 }
2701427024
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}
2702227037
...@@ -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 specific1965 /// 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;
47844784
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));
47914791
...@@ -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 }
48654868
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 }