diff --git a/bootstrap/Compilation.zig b/bootstrap/Compilation.zig index 27c1202..3f9a3f8 100644 --- a/bootstrap/Compilation.zig +++ b/bootstrap/Compilation.zig @@ -3065,7 +3065,7 @@ pub const V = struct { @"unreachable", pub const ConstantSlice = struct { - array: *Debug.Declaration.Global, + array: ?*Debug.Declaration.Global, start: usize, end: usize, type: Type.Index, @@ -4724,6 +4724,43 @@ pub const Builder = struct { else => |t| @panic(@tagName(t)), } }, + .address_of => { + assert(node.left != .null); + assert(node.right == .null); + + const appointee = unit.getNode(node.left); + switch (appointee.id) { + .anonymous_empty_literal => switch (type_expect) { + .type => |type_index| switch (unit.types.get(type_index).*) { + .slice => |slice| { + _ = slice; // autofix + var field_list = try UnpinnedArray(V.Comptime).initialize_with_capacity(context.my_allocator, 2); + + field_list.append_with_capacity(.undefined); + field_list.append_with_capacity(V.Comptime{ + .constant_int = .{ + .value = 0, + }, + }); + + const constant_slice = try unit.constant_slices.append(context.my_allocator, .{ + .array = null, + .start = 0, + .end = 0, + .type = type_index, + }); + + return .{ + .constant_slice = constant_slice, + }; + }, + else => |t| @panic(@tagName(t)), + }, + else => |t| @panic(@tagName(t)), + }, + else => |t| @panic(@tagName(t)), + } + }, else => |t| @panic(@tagName(t)), } } diff --git a/bootstrap/backend/llvm.zig b/bootstrap/backend/llvm.zig index 05cc5f2..c8b56ec 100644 --- a/bootstrap/backend/llvm.zig +++ b/bootstrap/backend/llvm.zig @@ -1952,15 +1952,23 @@ pub const LLVM = struct { const const_slice = unit.constant_slices.get(constant_slice_index); const const_slice_type = try llvm.getType(unit, context, const_slice.type); const slice_struct_type = const_slice_type.toStruct() orelse unreachable; - const ptr = llvm.global_variable_map.get(const_slice.array).?; - const signed = false; - assert(const_slice.start == 0); - const len = llvm.context.getConstantInt(@bitSizeOf(usize), const_slice.end, signed) orelse unreachable; - const slice_fields = [2]*LLVM.Value.Constant{ - ptr.toConstant(), - len.toConstant(), - }; + const slice_fields: [2]*LLVM.Value.Constant = if (const_slice.array) |array| b: { + const ptr = llvm.global_variable_map.get(array).?; + const signed = false; + assert(const_slice.start == 0); + const len = llvm.context.getConstantInt(@bitSizeOf(usize), const_slice.end, signed) orelse unreachable; + const slice_fields = [2]*LLVM.Value.Constant{ + ptr.toConstant(), + len.toConstant(), + }; + break :b slice_fields; + } else b: { + const ptr = llvm.pointer_type.?.toType().getPoison() orelse unreachable; + const len = llvm.context.getConstantInt(64, 0, false) orelse unreachable; + break :b .{ ptr.toConstant(), len.toConstant() }; + }; + const constant_slice = slice_struct_type.getConstant(&slice_fields, slice_fields.len) orelse unreachable; return constant_slice; } diff --git a/lib/std/build.nat b/lib/std/build.nat index 8e158bc..fd9fc65 100644 --- a/lib/std/build.nat +++ b/lib/std/build.nat @@ -8,6 +8,7 @@ const Executable = struct{ main_source_path: [:0]const u8, link_libc: bool = false, name: [:0]const u8, + c_source_files: []const []const u8 = .{}.&, const compile = fn(executable: Executable) *!void { const argument_count = std.start.argument_count; diff --git a/test/c-abi/first/build.nat b/test/c-abi/first/build.nat index 4fcca9c..5a3fda9 100644 --- a/test/c-abi/first/build.nat +++ b/test/c-abi/first/build.nat @@ -2,4 +2,15 @@ const std = #import("std"); const build = std.build; const main = fn() *!void { + const executable = Executable{ + .target = .{ + .cpu = .x86_64, + .os = .linux, + .abi = .gnu, + }, + .main_source_path = "main.nat", + .name = "first", + }; + + try executable.compile(); }