| author | |
| committer | |
| log | 24e7500c33fe5945039670fe6ced312dad381d37 |
| tree | d55b5a6e6c31ac68b2ded4d10c361b774567ee7d |
| parent | 3af842f0e89125e65a87e5752234bf7e0051aa12 |
| signature |
6 files changed, 73 insertions(+), 8 deletions(-)
lib/std/builtin.zig+11| ... | ... | @@ -1098,6 +1098,17 @@ pub const ExternOptions = struct { |
| 1098 | 1098 | is_thread_local: bool = false, |
| 1099 | 1099 | is_dll_import: bool = false, |
| 1100 | 1100 | relocation: Relocation = .any, |
| 1101 | decoration: ?Decoration = null, | |
| 1102 | ||
| 1103 | pub const Decoration = union(enum) { | |
| 1104 | location: u32, | |
| 1105 | descriptor: Descriptor, | |
| 1106 | ||
| 1107 | pub const Descriptor = struct { | |
| 1108 | binding: u32, | |
| 1109 | set: u32, | |
| 1110 | }; | |
| 1111 | }; | |
| 1101 | 1112 | |
| 1102 | 1113 | pub const Relocation = enum(u1) { |
| 1103 | 1114 | /// Any type of relocation is allowed. |
src/InternPool.zig+24-1| ... | ... | @@ -2247,6 +2247,7 @@ pub const Key = union(enum) { |
| 2247 | 2247 | is_threadlocal: bool, |
| 2248 | 2248 | is_dll_import: bool, |
| 2249 | 2249 | relocation: std.builtin.ExternOptions.Relocation, |
| 2250 | decoration: ?std.builtin.ExternOptions.Decoration, | |
| 2250 | 2251 | is_const: bool, |
| 2251 | 2252 | alignment: Alignment, |
| 2252 | 2253 | @"addrspace": std.builtin.AddressSpace, |
| ... | ... | @@ -6006,6 +6007,8 @@ pub const Tag = enum(u8) { |
| 6006 | 6007 | flags: Flags, |
| 6007 | 6008 | owner_nav: Nav.Index, |
| 6008 | 6009 | zir_index: TrackedInst.Index, |
| 6010 | location_or_descriptor_set: u32, | |
| 6011 | descriptor_binding: u32, | |
| 6009 | 6012 | |
| 6010 | 6013 | pub const Flags = packed struct(u32) { |
| 6011 | 6014 | linkage: std.builtin.GlobalLinkage, |
| ... | ... | @@ -6014,10 +6017,22 @@ pub const Tag = enum(u8) { |
| 6014 | 6017 | is_dll_import: bool, |
| 6015 | 6018 | relocation: std.builtin.ExternOptions.Relocation, |
| 6016 | 6019 | source: Source, |
| 6017 | _: u24 = 0, | |
| 6020 | decoration_type: DecorationType, | |
| 6021 | _: u22 = 0, | |
| 6018 | 6022 | |
| 6019 | 6023 | pub const Source = enum(u1) { builtin, syntax }; |
| 6024 | pub const DecorationType = enum(u2) { none, location, descriptor }; | |
| 6020 | 6025 | }; |
| 6026 | ||
| 6027 | pub fn decoration(self: Extern) ?std.builtin.ExternOptions.Decoration { | |
| 6028 | return switch (self.flags.decoration_type) { | |
| 6029 | .none => null, | |
| 6030 | .location => std.builtin.ExternOptions.Decoration{ | |
| 6031 | .location = self.location_or_descriptor_set, | |
| 6032 | }, | |
| 6033 | .descriptor => std.builtin.ExternOptions.Decoration{ .descriptor = .{ .set = self.location_or_descriptor_set, .binding = self.descriptor_binding } }, | |
| 6034 | }; | |
| 6035 | } | |
| 6021 | 6036 | }; |
| 6022 | 6037 | |
| 6023 | 6038 | /// Trailing: |
| ... | ... | @@ -7375,6 +7390,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 7375 | 7390 | .is_threadlocal = extra.flags.is_threadlocal, |
| 7376 | 7391 | .is_dll_import = extra.flags.is_dll_import, |
| 7377 | 7392 | .relocation = extra.flags.relocation, |
| 7393 | .decoration = extra.decoration(), | |
| 7378 | 7394 | .is_const = nav.status.fully_resolved.is_const, |
| 7379 | 7395 | .alignment = nav.status.fully_resolved.alignment, |
| 7380 | 7396 | .@"addrspace" = nav.status.fully_resolved.@"addrspace", |
| ... | ... | @@ -9264,15 +9280,22 @@ pub fn getExtern( |
| 9264 | 9280 | .@"linksection" = .none, |
| 9265 | 9281 | .@"addrspace" = key.@"addrspace", |
| 9266 | 9282 | }) catch unreachable; // capacity asserted above |
| 9283 | const decoration_type, const location_or_descriptor_set, const descriptor_binding = if (key.decoration) |decoration| switch (decoration) { | |
| 9284 | .location => |location| .{ Tag.Extern.Flags.DecorationType.location, location, undefined }, | |
| 9285 | .descriptor => |descriptor| .{ Tag.Extern.Flags.DecorationType.descriptor, descriptor.binding, descriptor.set }, | |
| 9286 | } else .{ Tag.Extern.Flags.DecorationType.none, undefined, undefined }; | |
| 9267 | 9287 | const extra_index = addExtraAssumeCapacity(extra, Tag.Extern{ |
| 9268 | 9288 | .ty = key.ty, |
| 9269 | 9289 | .lib_name = key.lib_name, |
| 9290 | .location_or_descriptor_set = location_or_descriptor_set, | |
| 9291 | .descriptor_binding = descriptor_binding, | |
| 9270 | 9292 | .flags = .{ |
| 9271 | 9293 | .linkage = key.linkage, |
| 9272 | 9294 | .visibility = key.visibility, |
| 9273 | 9295 | .is_threadlocal = key.is_threadlocal, |
| 9274 | 9296 | .is_dll_import = key.is_dll_import, |
| 9275 | 9297 | .relocation = key.relocation, |
| 9298 | .decoration_type = decoration_type, | |
| 9276 | 9299 | .source = key.source, |
| 9277 | 9300 | }, |
| 9278 | 9301 | .zir_index = key.zir_index, |
src/Sema.zig+8| ... | ... | @@ -25714,6 +25714,7 @@ fn resolveExternOptions( |
| 25714 | 25714 | is_thread_local: bool, |
| 25715 | 25715 | is_dll_import: bool, |
| 25716 | 25716 | relocation: std.builtin.ExternOptions.Relocation, |
| 25717 | decoration: ?std.builtin.ExternOptions.Decoration, | |
| 25717 | 25718 | } { |
| 25718 | 25719 | const pt = sema.pt; |
| 25719 | 25720 | const zcu = pt.zcu; |
| ... | ... | @@ -25730,6 +25731,7 @@ fn resolveExternOptions( |
| 25730 | 25731 | const thread_local_src = block.src(.{ .init_field_thread_local = src.offset.node_offset_builtin_call_arg.builtin_call_node }); |
| 25731 | 25732 | const dll_import_src = block.src(.{ .init_field_dll_import = src.offset.node_offset_builtin_call_arg.builtin_call_node }); |
| 25732 | 25733 | const relocation_src = block.src(.{ .init_field_relocation = src.offset.node_offset_builtin_call_arg.builtin_call_node }); |
| 25734 | const decoration_src = block.src(.{ .init_field_decoration = src.offset.node_offset_builtin_call_arg.builtin_call_node }); | |
| 25733 | 25735 | |
| 25734 | 25736 | const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src); |
| 25735 | 25737 | const name = try sema.toConstString(block, name_src, name_ref, .{ .simple = .extern_options }); |
| ... | ... | @@ -25764,6 +25766,10 @@ fn resolveExternOptions( |
| 25764 | 25766 | const relocation_val = try sema.resolveConstDefinedValue(block, relocation_src, relocation_ref, .{ .simple = .extern_options }); |
| 25765 | 25767 | const relocation = try sema.interpretBuiltinType(block, relocation_src, relocation_val, std.builtin.ExternOptions.Relocation); |
| 25766 | 25768 | |
| 25769 | const decoration_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "decoration", .no_embedded_nulls), decoration_src); | |
| 25770 | const decoration_val = try sema.resolveConstDefinedValue(block, decoration_src, decoration_ref, .{ .simple = .extern_options }); | |
| 25771 | const decoration = try sema.interpretBuiltinType(block, decoration_src, decoration_val, ?std.builtin.ExternOptions.Decoration); | |
| 25772 | ||
| 25767 | 25773 | if (name.len == 0) { |
| 25768 | 25774 | return sema.fail(block, name_src, "extern symbol name cannot be empty", .{}); |
| 25769 | 25775 | } |
| ... | ... | @@ -25780,6 +25786,7 @@ fn resolveExternOptions( |
| 25780 | 25786 | .is_thread_local = is_thread_local_val.toBool(), |
| 25781 | 25787 | .is_dll_import = is_dll_import_val.toBool(), |
| 25782 | 25788 | .relocation = relocation, |
| 25789 | .decoration = decoration, | |
| 25783 | 25790 | }; |
| 25784 | 25791 | } |
| 25785 | 25792 | |
| ... | ... | @@ -25839,6 +25846,7 @@ fn zirBuiltinExtern( |
| 25839 | 25846 | .is_threadlocal = options.is_thread_local, |
| 25840 | 25847 | .is_dll_import = options.is_dll_import, |
| 25841 | 25848 | .relocation = options.relocation, |
| 25849 | .decoration = options.decoration, | |
| 25842 | 25850 | .is_const = ptr_info.flags.is_const, |
| 25843 | 25851 | .alignment = ptr_info.flags.alignment, |
| 25844 | 25852 | .@"addrspace" = ptr_info.flags.address_space, |
src/Zcu.zig+3| ... | ... | @@ -2107,6 +2107,7 @@ pub const SrcLoc = struct { |
| 2107 | 2107 | .init_field_thread_local, |
| 2108 | 2108 | .init_field_dll_import, |
| 2109 | 2109 | .init_field_relocation, |
| 2110 | .init_field_decoration, | |
| 2110 | 2111 | => |builtin_call_node| { |
| 2111 | 2112 | const wanted = switch (src_loc.lazy) { |
| 2112 | 2113 | .init_field_name => "name", |
| ... | ... | @@ -2120,6 +2121,7 @@ pub const SrcLoc = struct { |
| 2120 | 2121 | .init_field_thread_local => "thread_local", |
| 2121 | 2122 | .init_field_dll_import => "dll_import", |
| 2122 | 2123 | .init_field_relocation => "relocation", |
| 2124 | .init_field_decoration => "decoration", | |
| 2123 | 2125 | else => unreachable, |
| 2124 | 2126 | }; |
| 2125 | 2127 | const tree = try src_loc.file_scope.getTree(zcu); |
| ... | ... | @@ -2600,6 +2602,7 @@ pub const LazySrcLoc = struct { |
| 2600 | 2602 | init_field_thread_local: Ast.Node.Offset, |
| 2601 | 2603 | init_field_dll_import: Ast.Node.Offset, |
| 2602 | 2604 | init_field_relocation: Ast.Node.Offset, |
| 2605 | init_field_decoration: Ast.Node.Offset, | |
| 2603 | 2606 | /// The source location points to the value of an item in a specific |
| 2604 | 2607 | /// case of a `switch`. |
| 2605 | 2608 | switch_case_item: SwitchItem, |
src/Zcu/PerThread.zig+2| ... | ... | @@ -1259,6 +1259,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1259 | 1259 | .visibility = .default, |
| 1260 | 1260 | .is_dll_import = false, |
| 1261 | 1261 | .relocation = .any, |
| 1262 | .decoration = null, | |
| 1262 | 1263 | .is_const = is_const, |
| 1263 | 1264 | .alignment = modifiers.alignment, |
| 1264 | 1265 | .@"addrspace" = modifiers.@"addrspace", |
| ... | ... | @@ -3458,6 +3459,7 @@ pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!V |
| 3458 | 3459 | .visibility = e.visibility, |
| 3459 | 3460 | .is_dll_import = e.is_dll_import, |
| 3460 | 3461 | .relocation = e.relocation, |
| 3462 | .decoration = e.decoration, | |
| 3461 | 3463 | .alignment = e.alignment, |
| 3462 | 3464 | .@"addrspace" = e.@"addrspace", |
| 3463 | 3465 | .zir_index = e.zir_index, |
src/codegen/spirv/CodeGen.zig+25-7| ... | ... | @@ -254,7 +254,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 254 | 254 | try cg.module.debugName(func_result_id, nav.fqn.toSlice(ip)); |
| 255 | 255 | }, |
| 256 | 256 | .global => { |
| 257 | assert(ip.indexToKey(val.toIntern()) == .@"extern"); | |
| 257 | const key = ip.indexToKey(val.toIntern()).@"extern"; | |
| 258 | 258 | |
| 259 | 259 | const storage_class = cg.module.storageClass(nav.getAddrspace()); |
| 260 | 260 | assert(storage_class != .generic); // These should be instance globals |
| ... | ... | @@ -277,14 +277,32 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 277 | 277 | } |
| 278 | 278 | } |
| 279 | 279 | |
| 280 | switch (ip.indexToKey(ty.toIntern())) { | |
| 281 | .func_type, .opaque_type => {}, | |
| 282 | else => { | |
| 283 | try cg.module.decorate(ptr_ty_id, .{ | |
| 284 | .array_stride = .{ .array_stride = @intCast(ty.abiSize(zcu)) }, | |
| 280 | try cg.module.decorate(ptr_ty_id, .{ | |
| 281 | .array_stride = .{ .array_stride = @intCast(ty.abiSize(zcu)) }, | |
| 282 | }); | |
| 283 | ||
| 284 | if (key.decoration) |decoration| switch (decoration) { | |
| 285 | .location => |location| { | |
| 286 | if (storage_class != .output and storage_class != .input and storage_class != .uniform_constant) { | |
| 287 | return cg.fail("storage class must be one of (output, input, uniform_constant) but is {s}", .{@tagName(storage_class)}); | |
| 288 | } | |
| 289 | try cg.module.decorate(result_id, .{ | |
| 290 | .location = .{ .location = location }, | |
| 285 | 291 | }); |
| 286 | 292 | }, |
| 287 | } | |
| 293 | .descriptor => |descriptor| { | |
| 294 | if (storage_class != .storage_buffer and storage_class != .uniform and storage_class != .uniform_constant) { | |
| 295 | return cg.fail("storage class must be one of (storage_buffer, uniform, uniform_constant) but is {s}", .{@tagName(storage_class)}); | |
| 296 | } | |
| 297 | try cg.module.decorate(result_id, .{ | |
| 298 | .binding = .{ .binding_point = descriptor.binding }, | |
| 299 | }); | |
| 300 | ||
| 301 | try cg.module.decorate(result_id, .{ | |
| 302 | .descriptor_set = .{ .descriptor_set = descriptor.set }, | |
| 303 | }); | |
| 304 | }, | |
| 305 | }; | |
| 288 | 306 | }, |
| 289 | 307 | else => {}, |
| 290 | 308 | } |