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 {
6868 link_once,
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 DllStorageClass = enum {
74 default,
75 import,
76 @"export",
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 SymbolVisibility = enum {
......@@ -683,6 +691,7 @@ pub const ExternOptions = struct {
683691 library_name: ?[]const u8 = null,
684692 linkage: GlobalLinkage = .strong,
685693 is_thread_local: bool = false,
694 dll_storage_class: DllStorageClass = .default,
686695};
687696
688697/// 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) {
20542054 is_const: bool,
20552055 is_threadlocal: bool,
20562056 is_weak_linkage: bool,
2057 is_dll_import: bool,
20572058 alignment: Alignment,
20582059 @"addrspace": std.builtin.AddressSpace,
20592060 /// The ZIR instruction which created this extern; used only for source locations.
......@@ -2675,6 +2676,7 @@ pub const Key = union(enum) {
26752676 asBytes(&e.ty) ++ asBytes(&e.lib_name) ++
26762677 asBytes(&e.is_const) ++ asBytes(&e.is_threadlocal) ++
26772678 asBytes(&e.is_weak_linkage) ++ asBytes(&e.alignment) ++
2679 asBytes(&e.is_dll_import) ++ asBytes(&e.alignment) ++
26782680 asBytes(&e.@"addrspace") ++ asBytes(&e.zir_index)),
26792681 };
26802682 }
......@@ -2771,6 +2773,7 @@ pub const Key = union(enum) {
27712773 a_info.is_const == b_info.is_const and
27722774 a_info.is_threadlocal == b_info.is_threadlocal and
27732775 a_info.is_weak_linkage == b_info.is_weak_linkage and
2776 a_info.is_dll_import == b_info.is_dll_import and
27742777 a_info.alignment == b_info.alignment and
27752778 a_info.@"addrspace" == b_info.@"addrspace" and
27762779 a_info.zir_index == b_info.zir_index;
......@@ -5370,7 +5373,8 @@ pub const Tag = enum(u8) {
53705373 is_const: bool,
53715374 is_threadlocal: bool,
53725375 is_weak_linkage: bool,
5373 _: u29 = 0,
5376 is_dll_import: bool,
5377 _: u28 = 0,
53745378 };
53755379 };
53765380
......@@ -6715,6 +6719,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
67156719 .is_const = extra.flags.is_const,
67166720 .is_threadlocal = extra.flags.is_threadlocal,
67176721 .is_weak_linkage = extra.flags.is_weak_linkage,
6722 .is_dll_import = extra.flags.is_dll_import,
67186723 .alignment = nav.status.resolved.alignment,
67196724 .@"addrspace" = nav.status.resolved.@"addrspace",
67206725 .zir_index = extra.zir_index,
......@@ -7381,6 +7386,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
73817386 .is_const = false,
73827387 .is_threadlocal = variable.is_threadlocal,
73837388 .is_weak_linkage = variable.is_weak_linkage,
7389 .is_dll_import = false,
73847390 },
73857391 }),
73867392 });
......@@ -8644,6 +8650,7 @@ pub fn getExtern(
86448650 .is_const = key.is_const,
86458651 .is_threadlocal = key.is_threadlocal,
86468652 .is_weak_linkage = key.is_weak_linkage,
8653 .is_dll_import = key.is_dll_import,
86478654 },
86488655 .zir_index = key.zir_index,
86498656 .owner_nav = owner_nav,
src/Sema.zig+16
......@@ -9960,6 +9960,7 @@ fn funcCommon(
99609960 .is_const = true,
99619961 .is_threadlocal = false,
99629962 .is_weak_linkage = false,
9963 .is_dll_import = false,
99639964 .alignment = alignment orelse .none,
99649965 .@"addrspace" = address_space orelse .generic,
99659966 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
......@@ -26505,6 +26506,7 @@ fn zirVarExtended(
2650526506 .is_const = small.is_const,
2650626507 .is_threadlocal = small.is_threadlocal,
2650726508 .is_weak_linkage = false,
26509 .is_dll_import = false,
2650826510 .alignment = alignment,
2650926511 .@"addrspace" = @"addrspace",
2651026512 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
......@@ -26958,6 +26960,7 @@ fn resolveExternOptions(
2695826960 library_name: InternPool.OptionalNullTerminatedString = .none,
2695926961 linkage: std.builtin.GlobalLinkage = .strong,
2696026962 is_thread_local: bool = false,
26963 dll_storage_class: std.builtin.DllStorageClass = .default,
2696126964} {
2696226965 const pt = sema.pt;
2696326966 const zcu = pt.zcu;
......@@ -26971,6 +26974,7 @@ fn resolveExternOptions(
2697126974 const library_src = block.src(.{ .init_field_library = src.offset.node_offset_builtin_call_arg.builtin_call_node });
2697226975 const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node });
2697326976 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
2697526979 const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src);
2697626980 const name = try sema.toConstString(block, name_src, name_ref, .{
......@@ -27004,6 +27008,12 @@ fn resolveExternOptions(
2700427008 break :library_name library_name;
2700527009 } 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
2700727017 if (name.len == 0) {
2700827018 return sema.fail(block, name_src, "extern symbol name cannot be empty", .{});
2700927019 }
......@@ -27012,11 +27022,16 @@ fn resolveExternOptions(
2701227022 return sema.fail(block, linkage_src, "extern symbol must use strong or weak linkage", .{});
2701327023 }
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
2701527029 return .{
2701627030 .name = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls),
2701727031 .library_name = try ip.getOrPutStringOpt(gpa, pt.tid, library_name, .no_embedded_nulls),
2701827032 .linkage = linkage,
2701927033 .is_thread_local = is_thread_local_val.toBool(),
27034 .dll_storage_class = dll_storage_class,
2702027035 };
2702127036}
2702227037
......@@ -27062,6 +27077,7 @@ fn zirBuiltinExtern(
2706227077 .is_const = ptr_info.flags.is_const,
2706327078 .is_threadlocal = options.is_thread_local,
2706427079 .is_weak_linkage = options.linkage == .weak,
27080 .is_dll_import = options.dll_storage_class == .import,
2706527081 .alignment = ptr_info.flags.alignment,
2706627082 .@"addrspace" = ptr_info.flags.address_space,
2706727083 // This instruction is just for source locations.
src/Zcu.zig+3
......@@ -1522,6 +1522,7 @@ pub const SrcLoc = struct {
15221522 .init_field_cache,
15231523 .init_field_library,
15241524 .init_field_thread_local,
1525 .init_field_dll_storage_class,
15251526 => |builtin_call_node| {
15261527 const wanted = switch (src_loc.lazy) {
15271528 .init_field_name => "name",
......@@ -1533,6 +1534,7 @@ pub const SrcLoc = struct {
15331534 .init_field_cache => "cache",
15341535 .init_field_library => "library",
15351536 .init_field_thread_local => "thread_local",
1537 .init_field_dll_storage_class => "dll_storage_class",
15361538 else => unreachable,
15371539 };
15381540 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -1959,6 +1961,7 @@ pub const LazySrcLoc = struct {
19591961 init_field_cache: i32,
19601962 init_field_library: i32,
19611963 init_field_thread_local: i32,
1964 init_field_dll_storage_class: i32,
19621965 /// The source location points to the value of an item in a specific
19631966 /// case of a `switch`.
19641967 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
27632763 .is_const = e.is_const,
27642764 .is_threadlocal = e.is_threadlocal,
27652765 .is_weak_linkage = e.is_weak_linkage,
2766 .is_dll_import = e.is_dll_import,
27662767 .alignment = e.alignment,
27672768 .@"addrspace" = e.@"addrspace",
27682769 .zir_index = e.zir_index,
src/codegen/llvm.zig+8-5
......@@ -4782,10 +4782,10 @@ pub const NavGen = struct {
47824782 const nav = ip.getNav(nav_index);
47834783 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)) {
4786 .variable => |variable| .{ false, variable.lib_name, variable.is_threadlocal, variable.is_weak_linkage, 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 },
4788 else => .{ false, .none, false, false, true, resolved.val, nav_index },
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, false, variable.init, variable.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, false, true, resolved.val, nav_index },
47894789 };
47904790 const ty = Type.fromInterned(nav.typeOf(ip));
47914791
......@@ -4860,8 +4860,11 @@ pub const NavGen = struct {
48604860 try global_index.rename(decl_name, &o.builder);
48614861 global_index.setLinkage(.external, &o.builder);
48624862 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) {
48644866 global_index.setDllStorageClass(.default, &o.builder);
4867 }
48654868
48664869 if (is_weak_linkage) global_index.setLinkage(.extern_weak, &o.builder);
48674870 }