aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-07-04 17:22:36 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-07-04 17:22:36 -0700
commitfbd6c883213ae9fce9734e2702cd6d3ef7691694 (patch)
tree54b3178757d827e2756165e123d4526332bc3a3a /src
parentf59bd2be539ce736d2ef04d16f48980d9c02a3ab (diff)
parent6fc9f6c5f6a067475f97cd16cb265332c8b7c6f3 (diff)
downloadzig-fbd6c883213ae9fce9734e2702cd6d3ef7691694.tar.gz
zig-fbd6c883213ae9fce9734e2702cd6d3ef7691694.zip
Merge remote-tracking branch 'origin/master' into llvm14
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig61
-rw-r--r--src/codegen/spirv/Section.zig10
-rw-r--r--src/link/Coff.zig153
3 files changed, 138 insertions, 86 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index b946e29057..e234255c6e 100644
--- a/src/Sema.zig
+++ b/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;
diff --git a/src/codegen/spirv/Section.zig b/src/codegen/spirv/Section.zig
index 6ed2de92f0..d21c2af8f1 100644
--- a/src/codegen/spirv/Section.zig
+++ b/src/codegen/spirv/Section.zig
@@ -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);
diff --git a/src/link/Coff.zig b/src/link/Coff.zig
index 0e7d7c89ee..1b5ddbbf8b 100644
--- a/src/link/Coff.zig
+++ b/src/link/Coff.zig
@@ -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 {