authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-15 18:04:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-15 18:04:37-07:00
log16bd0c63b4a8b1313bc05cb32b31e5345e467db3
tree5435d726f782bc442538c64318619c79409eba3e
parent99a2fc2cde4c193d11322b2b22086fb4bc99f9fc
parent7ccfb08a9389e4742e9a3237ce354c0492f7c040

Merge remote-tracking branch 'origin/master' into stage2-zig-cc

Pulling in the changes to libc_installation.zig

6 files changed, 79 insertions(+), 31 deletions(-)

ci/srht/on_master_success+1-1
...@@ -23,7 +23,7 @@ packages:...@@ -23,7 +23,7 @@ packages:
23 - jq23 - jq
24 - xz24 - xz
25secrets:25secrets:
26 - 6c60aaee-92e7-4e7d-812c-114817689b4d26 - 51bfddf5-86a6-4e01-8576-358c72a4a0a4
27sources:27sources:
28 - https://github.com/ziglang/zig28 - https://github.com/ziglang/zig
29tasks:29tasks:
lib/std/elf.zig+1-1
...@@ -471,7 +471,7 @@ pub const SectionHeaderIterator = struct {...@@ -471,7 +471,7 @@ pub const SectionHeaderIterator = struct {
471471
472 if (self.elf_header.is_64) {472 if (self.elf_header.is_64) {
473 var shdr: Elf64_Shdr = undefined;473 var shdr: Elf64_Shdr = undefined;
474 const offset = self.elf_header.phoff + @sizeOf(@TypeOf(shdr)) * self.index;474 const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index;
475 try preadNoEof(self.file, mem.asBytes(&shdr), offset);475 try preadNoEof(self.file, mem.asBytes(&shdr), offset);
476476
477 // ELF endianness matches native endianness.477 // ELF endianness matches native endianness.
lib/std/meta.zig+55-12
...@@ -717,7 +717,7 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -717,7 +717,7 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
717 },717 },
718 .Optional => |opt| {718 .Optional => |opt| {
719 if (@typeInfo(opt.child) == .Pointer) {719 if (@typeInfo(opt.child) == .Pointer) {
720 return @ptrCast(DestType, @alignCast(dest_ptr, target));720 return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
721 }721 }
722 },722 },
723 else => {},723 else => {},
...@@ -725,23 +725,24 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -725,23 +725,24 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
725 },725 },
726 .Optional => |dest_opt| {726 .Optional => |dest_opt| {
727 if (@typeInfo(dest_opt.child) == .Pointer) {727 if (@typeInfo(dest_opt.child) == .Pointer) {
728 const dest_ptr = @typeInfo(dest_opt.child).Pointer;
728 switch (@typeInfo(TargetType)) {729 switch (@typeInfo(TargetType)) {
729 .Int, .ComptimeInt => {730 .Int, .ComptimeInt => {
730 return @intToPtr(DestType, target);731 return @intToPtr(DestType, target);
731 },732 },
732 .Pointer => {733 .Pointer => {
733 return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target));734 return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
734 },735 },
735 .Optional => |target_opt| {736 .Optional => |target_opt| {
736 if (@typeInfo(target_opt.child) == .Pointer) {737 if (@typeInfo(target_opt.child) == .Pointer) {
737 return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target));738 return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
738 }739 }
739 },740 },
740 else => {},741 else => {},
741 }742 }
742 }743 }
743 },744 },
744 .Enum, .EnumLiteral => {745 .Enum => {
745 if (@typeInfo(TargetType) == .Int or @typeInfo(TargetType) == .ComptimeInt) {746 if (@typeInfo(TargetType) == .Int or @typeInfo(TargetType) == .ComptimeInt) {
746 return @intToEnum(DestType, target);747 return @intToEnum(DestType, target);
747 }748 }
...@@ -749,15 +750,18 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -749,15 +750,18 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
749 .Int, .ComptimeInt => {750 .Int, .ComptimeInt => {
750 switch (@typeInfo(TargetType)) {751 switch (@typeInfo(TargetType)) {
751 .Pointer => {752 .Pointer => {
752 return @as(DestType, @ptrToInt(target));753 return @intCast(DestType, @ptrToInt(target));
753 },754 },
754 .Optional => |opt| {755 .Optional => |opt| {
755 if (@typeInfo(opt.child) == .Pointer) {756 if (@typeInfo(opt.child) == .Pointer) {
756 return @as(DestType, @ptrToInt(target));757 return @intCast(DestType, @ptrToInt(target));
757 }758 }
758 },759 },
759 .Enum, .EnumLiteral => {760 .Enum => {
760 return @as(DestType, @enumToInt(target));761 return @intCast(DestType, @enumToInt(target));
762 },
763 .Int, .ComptimeInt => {
764 return @intCast(DestType, target);
761 },765 },
762 else => {},766 else => {},
763 }767 }
...@@ -776,10 +780,49 @@ test "std.meta.cast" {...@@ -776,10 +780,49 @@ test "std.meta.cast" {
776780
777 var i = @as(i64, 10);781 var i = @as(i64, 10);
778782
779 testing.expect(cast(?*c_void, 0) == @intToPtr(?*c_void, 0));
780 testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16));783 testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16));
781 testing.expect(cast(u64, @as(u32, 10)) == @as(u64, 10));
782 testing.expect(cast(E, 1) == .One);
783 testing.expect(cast(u8, E.Two) == 2);
784 testing.expect(cast(*u64, &i).* == @as(u64, 10));784 testing.expect(cast(*u64, &i).* == @as(u64, 10));
785 testing.expect(cast(*i64, @as(?*align(1) i64, &i)) == &i);
786
787 testing.expect(cast(?*u8, 2) == @intToPtr(*u8, 2));
788 testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i);
789 testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i);
790
791 testing.expect(cast(E, 1) == .One);
792
793 testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4)));
794 testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4)));
795 testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10)));
796 testing.expectEqual(@as(u8, 2), cast(u8, E.Two));
797}
798
799/// Given a value returns its size as C's sizeof operator would.
800/// This is for translate-c and is not intended for general use.
801pub fn sizeof(target: anytype) usize {
802 switch (@typeInfo(@TypeOf(target))) {
803 .Type => return @sizeOf(target),
804 .Float, .Int, .Struct, .Union, .Enum => return @sizeOf(@TypeOf(target)),
805 .ComptimeFloat => return @sizeOf(f64), // TODO c_double #3999
806 .ComptimeInt => {
807 // TODO to get the correct result we have to translate
808 // `1073741824 * 4` as `int(1073741824) *% int(4)` since
809 // sizeof(1073741824 * 4) != sizeof(4294967296).
810
811 // TODO test if target fits in int, long or long long
812 return @sizeOf(c_int);
813 },
814 else => @compileError("TODO implement std.meta.sizeof for type " ++ @typeName(@TypeOf(target))),
815 }
816}
817
818test "sizeof" {
819 const E = extern enum(c_int) { One, _ };
820 const S = extern struct { a: u32 };
821
822 testing.expect(sizeof(u32) == 4);
823 testing.expect(sizeof(@as(u32, 2)) == 4);
824 testing.expect(sizeof(2) == @sizeOf(c_int));
825 testing.expect(sizeof(E) == @sizeOf(c_int));
826 testing.expect(sizeof(E.One) == @sizeOf(c_int));
827 testing.expect(sizeof(S) == 4);
785}828}
src-self-hosted/libc_installation.zig+9-8
...@@ -10,6 +10,8 @@ const is_darwin = Target.current.isDarwin();...@@ -10,6 +10,8 @@ const is_darwin = Target.current.isDarwin();
10const is_windows = Target.current.os.tag == .windows;10const is_windows = Target.current.os.tag == .windows;
11const is_gnu = Target.current.isGnu();11const is_gnu = Target.current.isGnu();
1212
13const log = std.log.scoped(.libc_installation);
14
13usingnamespace @import("windows_sdk.zig");15usingnamespace @import("windows_sdk.zig");
1416
15// TODO https://github.com/ziglang/zig/issues/634517// TODO https://github.com/ziglang/zig/issues/6345
...@@ -40,7 +42,6 @@ pub const LibCInstallation = struct {...@@ -40,7 +42,6 @@ pub const LibCInstallation = struct {
40 pub fn parse(42 pub fn parse(
41 allocator: *Allocator,43 allocator: *Allocator,
42 libc_file: []const u8,44 libc_file: []const u8,
43 stderr: anytype,
44 ) !LibCInstallation {45 ) !LibCInstallation {
45 var self: LibCInstallation = .{};46 var self: LibCInstallation = .{};
4647
...@@ -65,7 +66,7 @@ pub const LibCInstallation = struct {...@@ -65,7 +66,7 @@ pub const LibCInstallation = struct {
65 if (line.len == 0 or line[0] == '#') continue;66 if (line.len == 0 or line[0] == '#') continue;
66 var line_it = std.mem.split(line, "=");67 var line_it = std.mem.split(line, "=");
67 const name = line_it.next() orelse {68 const name = line_it.next() orelse {
68 try stderr.print("missing equal sign after field name\n", .{});69 log.err("missing equal sign after field name\n", .{});
69 return error.ParseError;70 return error.ParseError;
70 };71 };
71 const value = line_it.rest();72 const value = line_it.rest();
...@@ -84,31 +85,31 @@ pub const LibCInstallation = struct {...@@ -84,31 +85,31 @@ pub const LibCInstallation = struct {
84 }85 }
85 inline for (fields) |field, i| {86 inline for (fields) |field, i| {
86 if (!found_keys[i].found) {87 if (!found_keys[i].found) {
87 try stderr.print("missing field: {}\n", .{field.name});88 log.err("missing field: {}\n", .{field.name});
88 return error.ParseError;89 return error.ParseError;
89 }90 }
90 }91 }
91 if (self.include_dir == null) {92 if (self.include_dir == null) {
92 try stderr.print("include_dir may not be empty\n", .{});93 log.err("include_dir may not be empty\n", .{});
93 return error.ParseError;94 return error.ParseError;
94 }95 }
95 if (self.sys_include_dir == null) {96 if (self.sys_include_dir == null) {
96 try stderr.print("sys_include_dir may not be empty\n", .{});97 log.err("sys_include_dir may not be empty\n", .{});
97 return error.ParseError;98 return error.ParseError;
98 }99 }
99 if (self.crt_dir == null and !is_darwin) {100 if (self.crt_dir == null and !is_darwin) {
100 try stderr.print("crt_dir may not be empty for {}\n", .{@tagName(Target.current.os.tag)});101 log.err("crt_dir may not be empty for {}\n", .{@tagName(Target.current.os.tag)});
101 return error.ParseError;102 return error.ParseError;
102 }103 }
103 if (self.msvc_lib_dir == null and is_windows and !is_gnu) {104 if (self.msvc_lib_dir == null and is_windows and !is_gnu) {
104 try stderr.print("msvc_lib_dir may not be empty for {}-{}\n", .{105 log.err("msvc_lib_dir may not be empty for {}-{}\n", .{
105 @tagName(Target.current.os.tag),106 @tagName(Target.current.os.tag),
106 @tagName(Target.current.abi),107 @tagName(Target.current.abi),
107 });108 });
108 return error.ParseError;109 return error.ParseError;
109 }110 }
110 if (self.kernel32_lib_dir == null and is_windows and !is_gnu) {111 if (self.kernel32_lib_dir == null and is_windows and !is_gnu) {
111 try stderr.print("kernel32_lib_dir may not be empty for {}-{}\n", .{112 log.err("kernel32_lib_dir may not be empty for {}-{}\n", .{
112 @tagName(Target.current.os.tag),113 @tagName(Target.current.os.tag),
113 @tagName(Target.current.abi),114 @tagName(Target.current.abi),
114 });115 });
src-self-hosted/stage2.zig+1-5
...@@ -615,12 +615,9 @@ const Stage2LibCInstallation = extern struct {...@@ -615,12 +615,9 @@ const Stage2LibCInstallation = extern struct {
615615
616// ABI warning616// ABI warning
617export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error {617export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error {
618 stderr_file = std.io.getStdErr();
619 stderr = stderr_file.outStream();
620 const libc_file = mem.spanZ(libc_file_z);618 const libc_file = mem.spanZ(libc_file_z);
621 var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file, stderr) catch |err| switch (err) {619 var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file) catch |err| switch (err) {
622 error.ParseError => return .SemanticAnalyzeFail,620 error.ParseError => return .SemanticAnalyzeFail,
623 error.DiskQuota => return .DiskQuota,
624 error.FileTooBig => return .FileTooBig,621 error.FileTooBig => return .FileTooBig,
625 error.InputOutput => return .FileSystem,622 error.InputOutput => return .FileSystem,
626 error.NoSpaceLeft => return .NoSpaceLeft,623 error.NoSpaceLeft => return .NoSpaceLeft,
...@@ -629,7 +626,6 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [...@@ -629,7 +626,6 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [
629 error.SystemResources => return .SystemResources,626 error.SystemResources => return .SystemResources,
630 error.OperationAborted => return .OperationAborted,627 error.OperationAborted => return .OperationAborted,
631 error.WouldBlock => unreachable,628 error.WouldBlock => unreachable,
632 error.NotOpenForWriting => unreachable,
633 error.NotOpenForReading => unreachable,629 error.NotOpenForReading => unreachable,
634 error.Unexpected => return .Unexpected,630 error.Unexpected => return .Unexpected,
635 error.IsDir => return .IsDir,631 error.IsDir => return .IsDir,
src-self-hosted/translate_c.zig+12-4
...@@ -6324,10 +6324,18 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast....@@ -6324,10 +6324,18 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.
6324 break :blk inner;6324 break :blk inner;
6325 } else try parseCPrefixOpExpr(c, m, scope);6325 } else try parseCPrefixOpExpr(c, m, scope);
63266326
6327 const builtin_call = try c.createBuiltinCall("@sizeOf", 1);6327 //(@import("std").meta.sizeof(dest, x))
6328 builtin_call.params()[0] = inner;6328 const import_fn_call = try c.createBuiltinCall("@import", 1);
6329 builtin_call.rparen_token = try appendToken(c, .RParen, ")");6329 const std_node = try transCreateNodeStringLiteral(c, "\"std\"");
6330 return &builtin_call.base;6330 import_fn_call.params()[0] = std_node;
6331 import_fn_call.rparen_token = try appendToken(c, .RParen, ")");
6332 const inner_field_access = try transCreateNodeFieldAccess(c, &import_fn_call.base, "meta");
6333 const outer_field_access = try transCreateNodeFieldAccess(c, inner_field_access, "sizeof");
6334
6335 const sizeof_call = try c.createCall(outer_field_access, 1);
6336 sizeof_call.params()[0] = inner;
6337 sizeof_call.rtoken = try appendToken(c, .RParen, ")");
6338 return &sizeof_call.base;
6331 },6339 },
6332 .Keyword_alignof => {6340 .Keyword_alignof => {
6333 // TODO this won't work if using <stdalign.h>'s6341 // TODO this won't work if using <stdalign.h>'s