diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/InternPool.zig | 9 | ||||
| -rw-r--r-- | src/Sema.zig | 16 | ||||
| -rw-r--r-- | src/Zcu.zig | 3 | ||||
| -rw-r--r-- | src/Zcu/PerThread.zig | 1 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 13 |
5 files changed, 36 insertions, 6 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig index 4315855d83..e396b85059 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -2054,6 +2054,7 @@ pub const Key = union(enum) { is_const: bool, is_threadlocal: bool, is_weak_linkage: bool, + is_dll_import: bool, alignment: Alignment, @"addrspace": std.builtin.AddressSpace, /// The ZIR instruction which created this extern; used only for source locations. @@ -2675,6 +2676,7 @@ pub const Key = union(enum) { asBytes(&e.ty) ++ asBytes(&e.lib_name) ++ asBytes(&e.is_const) ++ asBytes(&e.is_threadlocal) ++ asBytes(&e.is_weak_linkage) ++ asBytes(&e.alignment) ++ + asBytes(&e.is_dll_import) ++ asBytes(&e.alignment) ++ asBytes(&e.@"addrspace") ++ asBytes(&e.zir_index)), }; } @@ -2771,6 +2773,7 @@ pub const Key = union(enum) { a_info.is_const == b_info.is_const and a_info.is_threadlocal == b_info.is_threadlocal and a_info.is_weak_linkage == b_info.is_weak_linkage and + a_info.is_dll_import == b_info.is_dll_import and a_info.alignment == b_info.alignment and a_info.@"addrspace" == b_info.@"addrspace" and a_info.zir_index == b_info.zir_index; @@ -5370,7 +5373,8 @@ pub const Tag = enum(u8) { is_const: bool, is_threadlocal: bool, is_weak_linkage: bool, - _: u29 = 0, + is_dll_import: bool, + _: u28 = 0, }; }; @@ -6715,6 +6719,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { .is_const = extra.flags.is_const, .is_threadlocal = extra.flags.is_threadlocal, .is_weak_linkage = extra.flags.is_weak_linkage, + .is_dll_import = extra.flags.is_dll_import, .alignment = nav.status.resolved.alignment, .@"addrspace" = nav.status.resolved.@"addrspace", .zir_index = extra.zir_index, @@ -7381,6 +7386,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All .is_const = false, .is_threadlocal = variable.is_threadlocal, .is_weak_linkage = variable.is_weak_linkage, + .is_dll_import = false, }, }), }); @@ -8644,6 +8650,7 @@ pub fn getExtern( .is_const = key.is_const, .is_threadlocal = key.is_threadlocal, .is_weak_linkage = key.is_weak_linkage, + .is_dll_import = key.is_dll_import, }, .zir_index = key.zir_index, .owner_nav = owner_nav, diff --git a/src/Sema.zig b/src/Sema.zig index b8f35c5067..95586e2161 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9960,6 +9960,7 @@ fn funcCommon( .is_const = true, .is_threadlocal = false, .is_weak_linkage = false, + .is_dll_import = false, .alignment = alignment orelse .none, .@"addrspace" = address_space orelse .generic, .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction @@ -26505,6 +26506,7 @@ fn zirVarExtended( .is_const = small.is_const, .is_threadlocal = small.is_threadlocal, .is_weak_linkage = false, + .is_dll_import = false, .alignment = alignment, .@"addrspace" = @"addrspace", .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction @@ -26958,6 +26960,7 @@ fn resolveExternOptions( library_name: InternPool.OptionalNullTerminatedString = .none, linkage: std.builtin.GlobalLinkage = .strong, is_thread_local: bool = false, + dll_storage_class: std.builtin.DllStorageClass = .default, } { const pt = sema.pt; const zcu = pt.zcu; @@ -26971,6 +26974,7 @@ fn resolveExternOptions( const library_src = block.src(.{ .init_field_library = src.offset.node_offset_builtin_call_arg.builtin_call_node }); const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node }); const thread_local_src = block.src(.{ .init_field_thread_local = src.offset.node_offset_builtin_call_arg.builtin_call_node }); + const dll_storage_class_src = block.src(.{ .init_field_dll_storage_class = src.offset.node_offset_builtin_call_arg.builtin_call_node }); const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src); const name = try sema.toConstString(block, name_src, name_ref, .{ @@ -27004,6 +27008,12 @@ fn resolveExternOptions( break :library_name library_name; } else null; + 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); + const dll_storage_class_val = try sema.resolveConstDefinedValue(block, dll_storage_class_src, dll_storage_class_ref, .{ + .needed_comptime_reason = "dll_storage_class of the extern symbol must be comptime-known", + }); + const dll_storage_class = zcu.toEnum(std.builtin.DllStorageClass, dll_storage_class_val); + if (name.len == 0) { return sema.fail(block, name_src, "extern symbol name cannot be empty", .{}); } @@ -27012,11 +27022,16 @@ fn resolveExternOptions( return sema.fail(block, linkage_src, "extern symbol must use strong or weak linkage", .{}); } + if (dll_storage_class == .@"export") { + return sema.fail(block, dll_storage_class_src, "extern symbol cannot have export dll storage class", .{}); + } + return .{ .name = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls), .library_name = try ip.getOrPutStringOpt(gpa, pt.tid, library_name, .no_embedded_nulls), .linkage = linkage, .is_thread_local = is_thread_local_val.toBool(), + .dll_storage_class = dll_storage_class, }; } @@ -27062,6 +27077,7 @@ fn zirBuiltinExtern( .is_const = ptr_info.flags.is_const, .is_threadlocal = options.is_thread_local, .is_weak_linkage = options.linkage == .weak, + .is_dll_import = options.dll_storage_class == .import, .alignment = ptr_info.flags.alignment, .@"addrspace" = ptr_info.flags.address_space, // This instruction is just for source locations. diff --git a/src/Zcu.zig b/src/Zcu.zig index eeff80ee30..144b1ab627 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -1522,6 +1522,7 @@ pub const SrcLoc = struct { .init_field_cache, .init_field_library, .init_field_thread_local, + .init_field_dll_storage_class, => |builtin_call_node| { const wanted = switch (src_loc.lazy) { .init_field_name => "name", @@ -1533,6 +1534,7 @@ pub const SrcLoc = struct { .init_field_cache => "cache", .init_field_library => "library", .init_field_thread_local => "thread_local", + .init_field_dll_storage_class => "dll_storage_class", else => unreachable, }; const tree = try src_loc.file_scope.getTree(gpa); @@ -1959,6 +1961,7 @@ pub const LazySrcLoc = struct { init_field_cache: i32, init_field_library: i32, init_field_thread_local: i32, + init_field_dll_storage_class: i32, /// The source location points to the value of an item in a specific /// case of a `switch`. switch_case_item: SwitchItem, diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 32928e17e1..820e053336 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -2763,6 +2763,7 @@ pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!V .is_const = e.is_const, .is_threadlocal = e.is_threadlocal, .is_weak_linkage = e.is_weak_linkage, + .is_dll_import = e.is_dll_import, .alignment = e.alignment, .@"addrspace" = e.@"addrspace", .zir_index = e.zir_index, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4b4ced9a6f..a2c2f98a21 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -4782,10 +4782,10 @@ pub const NavGen = struct { const nav = ip.getNav(nav_index); const resolved = nav.status.resolved; - 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)) { - .variable => |variable| .{ false, variable.lib_name, variable.is_threadlocal, variable.is_weak_linkage, false, variable.init, variable.owner_nav }, - .@"extern" => |@"extern"| .{ true, @"extern".lib_name, @"extern".is_threadlocal, @"extern".is_weak_linkage, @"extern".is_const, .none, @"extern".owner_nav }, - else => .{ false, .none, false, false, true, resolved.val, nav_index }, + 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)) { + .variable => |variable| .{ false, variable.lib_name, variable.is_threadlocal, variable.is_weak_linkage, false, false, variable.init, variable.owner_nav }, + .@"extern" => |@"extern"| .{ true, @"extern".lib_name, @"extern".is_threadlocal, @"extern".is_weak_linkage, @"extern".is_dll_import, @"extern".is_const, .none, @"extern".owner_nav }, + else => .{ false, .none, false, false, false, true, resolved.val, nav_index }, }; const ty = Type.fromInterned(nav.typeOf(ip)); @@ -4860,8 +4860,11 @@ pub const NavGen = struct { try global_index.rename(decl_name, &o.builder); global_index.setLinkage(.external, &o.builder); global_index.setUnnamedAddr(.default, &o.builder); - if (zcu.comp.config.dll_export_fns) + if (is_dll_import) { + global_index.setDllStorageClass(.dllimport, &o.builder); + } else if (zcu.comp.config.dll_export_fns) { global_index.setDllStorageClass(.default, &o.builder); + } if (is_weak_linkage) global_index.setLinkage(.extern_weak, &o.builder); } |
