mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Merge remote-tracking branch 'origin/master' into llvm14
This commit is contained in:
commit
fbd6c88321
@ -513,7 +513,8 @@ const WindowsThreadImpl = struct {
|
||||
errdefer assert(windows.kernel32.HeapFree(heap_handle, 0, alloc_ptr) != 0);
|
||||
|
||||
const instance_bytes = @ptrCast([*]u8, alloc_ptr)[0..alloc_bytes];
|
||||
const instance = std.heap.FixedBufferAllocator.init(instance_bytes).allocator().create(Instance) catch unreachable;
|
||||
var fba = std.heap.FixedBufferAllocator.init(instance_bytes);
|
||||
const instance = fba.allocator().create(Instance) catch unreachable;
|
||||
instance.* = .{
|
||||
.fn_args = args,
|
||||
.thread = .{
|
||||
|
||||
61
src/Sema.zig
61
src/Sema.zig
@ -5736,6 +5736,7 @@ fn instantiateGenericCall(
|
||||
const arg_src = call_src; // TODO better source location
|
||||
const arg_ty = sema.typeOf(uncasted_args[i]);
|
||||
const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i]);
|
||||
try sema.resolveLazyValue(block, arg_src, arg_val);
|
||||
arg_val.hash(arg_ty, &hasher, mod);
|
||||
if (is_anytype) {
|
||||
arg_ty.hashWithHasher(&hasher, mod);
|
||||
@ -26079,12 +26080,12 @@ fn intFitsInType(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
src: LazySrcLoc,
|
||||
self: Value,
|
||||
val: Value,
|
||||
ty: Type,
|
||||
vector_index: ?*usize,
|
||||
) CompileError!bool {
|
||||
const target = sema.mod.getTarget();
|
||||
switch (self.tag()) {
|
||||
switch (val.tag()) {
|
||||
.zero,
|
||||
.undef,
|
||||
.bool_false,
|
||||
@ -26104,30 +26105,38 @@ fn intFitsInType(
|
||||
else => unreachable,
|
||||
},
|
||||
|
||||
.lazy_align => {
|
||||
const info = ty.intInfo(target);
|
||||
const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
|
||||
// If it is u16 or bigger we know the alignment fits without resolving it.
|
||||
if (info.bits >= max_needed_bits) return true;
|
||||
const x = try sema.typeAbiAlignment(block, src, self.castTag(.lazy_align).?.data);
|
||||
if (x == 0) return true;
|
||||
const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
|
||||
return info.bits >= actual_needed_bits;
|
||||
.lazy_align => switch (ty.zigTypeTag()) {
|
||||
.Int => {
|
||||
const info = ty.intInfo(target);
|
||||
const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
|
||||
// If it is u16 or bigger we know the alignment fits without resolving it.
|
||||
if (info.bits >= max_needed_bits) return true;
|
||||
const x = try sema.typeAbiAlignment(block, src, val.castTag(.lazy_align).?.data);
|
||||
if (x == 0) return true;
|
||||
const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
|
||||
return info.bits >= actual_needed_bits;
|
||||
},
|
||||
.ComptimeInt => return true,
|
||||
else => unreachable,
|
||||
},
|
||||
.lazy_size => {
|
||||
const info = ty.intInfo(target);
|
||||
const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
|
||||
// If it is u64 or bigger we know the size fits without resolving it.
|
||||
if (info.bits >= max_needed_bits) return true;
|
||||
const x = try sema.typeAbiSize(block, src, self.castTag(.lazy_size).?.data);
|
||||
if (x == 0) return true;
|
||||
const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
|
||||
return info.bits >= actual_needed_bits;
|
||||
.lazy_size => switch (ty.zigTypeTag()) {
|
||||
.Int => {
|
||||
const info = ty.intInfo(target);
|
||||
const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
|
||||
// If it is u64 or bigger we know the size fits without resolving it.
|
||||
if (info.bits >= max_needed_bits) return true;
|
||||
const x = try sema.typeAbiSize(block, src, val.castTag(.lazy_size).?.data);
|
||||
if (x == 0) return true;
|
||||
const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
|
||||
return info.bits >= actual_needed_bits;
|
||||
},
|
||||
.ComptimeInt => return true,
|
||||
else => unreachable,
|
||||
},
|
||||
|
||||
.int_u64 => switch (ty.zigTypeTag()) {
|
||||
.Int => {
|
||||
const x = self.castTag(.int_u64).?.data;
|
||||
const x = val.castTag(.int_u64).?.data;
|
||||
if (x == 0) return true;
|
||||
const info = ty.intInfo(target);
|
||||
const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
|
||||
@ -26138,13 +26147,13 @@ fn intFitsInType(
|
||||
},
|
||||
.int_i64 => switch (ty.zigTypeTag()) {
|
||||
.Int => {
|
||||
const x = self.castTag(.int_i64).?.data;
|
||||
const x = val.castTag(.int_i64).?.data;
|
||||
if (x == 0) return true;
|
||||
const info = ty.intInfo(target);
|
||||
if (info.signedness == .unsigned and x < 0)
|
||||
return false;
|
||||
var buffer: Value.BigIntSpace = undefined;
|
||||
return (try self.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits);
|
||||
return (try val.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits);
|
||||
},
|
||||
.ComptimeInt => return true,
|
||||
else => unreachable,
|
||||
@ -26152,7 +26161,7 @@ fn intFitsInType(
|
||||
.int_big_positive => switch (ty.zigTypeTag()) {
|
||||
.Int => {
|
||||
const info = ty.intInfo(target);
|
||||
return self.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
|
||||
return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
|
||||
},
|
||||
.ComptimeInt => return true,
|
||||
else => unreachable,
|
||||
@ -26160,7 +26169,7 @@ fn intFitsInType(
|
||||
.int_big_negative => switch (ty.zigTypeTag()) {
|
||||
.Int => {
|
||||
const info = ty.intInfo(target);
|
||||
return self.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
|
||||
return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
|
||||
},
|
||||
.ComptimeInt => return true,
|
||||
else => unreachable,
|
||||
@ -26191,7 +26200,7 @@ fn intFitsInType(
|
||||
|
||||
.aggregate => {
|
||||
assert(ty.zigTypeTag() == .Vector);
|
||||
for (self.castTag(.aggregate).?.data) |elem, i| {
|
||||
for (val.castTag(.aggregate).?.data) |elem, i| {
|
||||
if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) {
|
||||
if (vector_index) |some| some.* = i;
|
||||
return false;
|
||||
|
||||
@ -328,6 +328,8 @@ fn extendedUnionSize(comptime Operand: type, operand: Operand) usize {
|
||||
}
|
||||
|
||||
test "SPIR-V Section emit() - no operands" {
|
||||
if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
var section = Section{};
|
||||
defer section.deinit(std.testing.allocator);
|
||||
|
||||
@ -337,6 +339,8 @@ test "SPIR-V Section emit() - no operands" {
|
||||
}
|
||||
|
||||
test "SPIR-V Section emit() - simple" {
|
||||
if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
var section = Section{};
|
||||
defer section.deinit(std.testing.allocator);
|
||||
|
||||
@ -353,6 +357,8 @@ test "SPIR-V Section emit() - simple" {
|
||||
}
|
||||
|
||||
test "SPIR-V Section emit() - string" {
|
||||
if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
var section = Section{};
|
||||
defer section.deinit(std.testing.allocator);
|
||||
|
||||
@ -378,6 +384,8 @@ test "SPIR-V Section emit() - string" {
|
||||
}
|
||||
|
||||
test "SPIR-V Section emit()- extended mask" {
|
||||
if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
var section = Section{};
|
||||
defer section.deinit(std.testing.allocator);
|
||||
|
||||
@ -402,6 +410,8 @@ test "SPIR-V Section emit()- extended mask" {
|
||||
}
|
||||
|
||||
test "SPIR-V Section emit() - extended union" {
|
||||
if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
var section = Section{};
|
||||
defer section.deinit(std.testing.allocator);
|
||||
|
||||
|
||||
@ -809,6 +809,36 @@ pub fn updateDeclExports(
|
||||
if (build_options.skip_non_native and builtin.object_format != .coff) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
|
||||
// Even in the case of LLVM, we need to notice certain exported symbols in order to
|
||||
// detect the default subsystem.
|
||||
for (exports) |exp| {
|
||||
const exported_decl = module.declPtr(exp.exported_decl);
|
||||
if (exported_decl.getFunction() == null) continue;
|
||||
const winapi_cc = switch (self.base.options.target.cpu.arch) {
|
||||
.i386 => std.builtin.CallingConvention.Stdcall,
|
||||
else => std.builtin.CallingConvention.C,
|
||||
};
|
||||
const decl_cc = exported_decl.ty.fnCallingConvention();
|
||||
if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and
|
||||
self.base.options.link_libc)
|
||||
{
|
||||
module.stage1_flags.have_c_main = true;
|
||||
} else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {
|
||||
if (mem.eql(u8, exp.options.name, "WinMain")) {
|
||||
module.stage1_flags.have_winmain = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "wWinMain")) {
|
||||
module.stage1_flags.have_wwinmain = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) {
|
||||
module.stage1_flags.have_winmain_crt_startup = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) {
|
||||
module.stage1_flags.have_wwinmain_crt_startup = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) {
|
||||
module.stage1_flags.have_dllmain_crt_startup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports);
|
||||
}
|
||||
@ -1114,17 +1144,6 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
|
||||
try argv.append("-dynamicbase");
|
||||
}
|
||||
|
||||
const subsystem_suffix = ss: {
|
||||
if (self.base.options.major_subsystem_version) |major| {
|
||||
if (self.base.options.minor_subsystem_version) |minor| {
|
||||
break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor });
|
||||
} else {
|
||||
break :ss try allocPrint(arena, ",{d}", .{major});
|
||||
}
|
||||
}
|
||||
break :ss "";
|
||||
};
|
||||
|
||||
try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path}));
|
||||
|
||||
if (self.base.options.implib_emit) |emit| {
|
||||
@ -1186,57 +1205,71 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
|
||||
}
|
||||
break :blk null;
|
||||
};
|
||||
|
||||
const Mode = enum { uefi, win32 };
|
||||
const mode: Mode = mode: {
|
||||
if (resolved_subsystem) |subsystem| switch (subsystem) {
|
||||
.Console => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.EfiApplication => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiBootServiceDriver => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiRom => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiRuntimeDriver => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.Native => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.Posix => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.Windows => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
if (resolved_subsystem) |subsystem| {
|
||||
const subsystem_suffix = ss: {
|
||||
if (self.base.options.major_subsystem_version) |major| {
|
||||
if (self.base.options.minor_subsystem_version) |minor| {
|
||||
break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor });
|
||||
} else {
|
||||
break :ss try allocPrint(arena, ",{d}", .{major});
|
||||
}
|
||||
}
|
||||
break :ss "";
|
||||
};
|
||||
|
||||
switch (subsystem) {
|
||||
.Console => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.EfiApplication => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiBootServiceDriver => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiRom => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiRuntimeDriver => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.Native => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.Posix => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.Windows => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
}
|
||||
} else if (target.os.tag == .uefi) {
|
||||
break :mode .uefi;
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user