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

Pulling in the changes to libc_installation.zig
This commit is contained in:
Andrew Kelley
2020-09-15 18:04:37 -07:00
6 changed files with 79 additions and 31 deletions

View File

@@ -23,7 +23,7 @@ packages:
- jq
- xz
secrets:
- 6c60aaee-92e7-4e7d-812c-114817689b4d
- 51bfddf5-86a6-4e01-8576-358c72a4a0a4
sources:
- https://github.com/ziglang/zig
tasks:

View File

@@ -471,7 +471,7 @@ pub const SectionHeaderIterator = struct {
if (self.elf_header.is_64) {
var shdr: Elf64_Shdr = undefined;
const offset = self.elf_header.phoff + @sizeOf(@TypeOf(shdr)) * self.index;
const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index;
try preadNoEof(self.file, mem.asBytes(&shdr), offset);
// ELF endianness matches native endianness.

View File

@@ -717,7 +717,7 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
},
.Optional => |opt| {
if (@typeInfo(opt.child) == .Pointer) {
return @ptrCast(DestType, @alignCast(dest_ptr, target));
return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
}
},
else => {},
@@ -725,23 +725,24 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
},
.Optional => |dest_opt| {
if (@typeInfo(dest_opt.child) == .Pointer) {
const dest_ptr = @typeInfo(dest_opt.child).Pointer;
switch (@typeInfo(TargetType)) {
.Int, .ComptimeInt => {
return @intToPtr(DestType, target);
},
.Pointer => {
return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target));
return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
},
.Optional => |target_opt| {
if (@typeInfo(target_opt.child) == .Pointer) {
return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target));
return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
}
},
else => {},
}
}
},
.Enum, .EnumLiteral => {
.Enum => {
if (@typeInfo(TargetType) == .Int or @typeInfo(TargetType) == .ComptimeInt) {
return @intToEnum(DestType, target);
}
@@ -749,15 +750,18 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
.Int, .ComptimeInt => {
switch (@typeInfo(TargetType)) {
.Pointer => {
return @as(DestType, @ptrToInt(target));
return @intCast(DestType, @ptrToInt(target));
},
.Optional => |opt| {
if (@typeInfo(opt.child) == .Pointer) {
return @as(DestType, @ptrToInt(target));
return @intCast(DestType, @ptrToInt(target));
}
},
.Enum, .EnumLiteral => {
return @as(DestType, @enumToInt(target));
.Enum => {
return @intCast(DestType, @enumToInt(target));
},
.Int, .ComptimeInt => {
return @intCast(DestType, target);
},
else => {},
}
@@ -776,10 +780,49 @@ test "std.meta.cast" {
var i = @as(i64, 10);
testing.expect(cast(?*c_void, 0) == @intToPtr(?*c_void, 0));
testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16));
testing.expect(cast(u64, @as(u32, 10)) == @as(u64, 10));
testing.expect(cast(E, 1) == .One);
testing.expect(cast(u8, E.Two) == 2);
testing.expect(cast(*u64, &i).* == @as(u64, 10));
testing.expect(cast(*i64, @as(?*align(1) i64, &i)) == &i);
testing.expect(cast(?*u8, 2) == @intToPtr(*u8, 2));
testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i);
testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i);
testing.expect(cast(E, 1) == .One);
testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4)));
testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4)));
testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10)));
testing.expectEqual(@as(u8, 2), cast(u8, E.Two));
}
/// Given a value returns its size as C's sizeof operator would.
/// This is for translate-c and is not intended for general use.
pub fn sizeof(target: anytype) usize {
switch (@typeInfo(@TypeOf(target))) {
.Type => return @sizeOf(target),
.Float, .Int, .Struct, .Union, .Enum => return @sizeOf(@TypeOf(target)),
.ComptimeFloat => return @sizeOf(f64), // TODO c_double #3999
.ComptimeInt => {
// TODO to get the correct result we have to translate
// `1073741824 * 4` as `int(1073741824) *% int(4)` since
// sizeof(1073741824 * 4) != sizeof(4294967296).
// TODO test if target fits in int, long or long long
return @sizeOf(c_int);
},
else => @compileError("TODO implement std.meta.sizeof for type " ++ @typeName(@TypeOf(target))),
}
}
test "sizeof" {
const E = extern enum(c_int) { One, _ };
const S = extern struct { a: u32 };
testing.expect(sizeof(u32) == 4);
testing.expect(sizeof(@as(u32, 2)) == 4);
testing.expect(sizeof(2) == @sizeOf(c_int));
testing.expect(sizeof(E) == @sizeOf(c_int));
testing.expect(sizeof(E.One) == @sizeOf(c_int));
testing.expect(sizeof(S) == 4);
}

View File

@@ -10,6 +10,8 @@ const is_darwin = Target.current.isDarwin();
const is_windows = Target.current.os.tag == .windows;
const is_gnu = Target.current.isGnu();
const log = std.log.scoped(.libc_installation);
usingnamespace @import("windows_sdk.zig");
// TODO https://github.com/ziglang/zig/issues/6345
@@ -40,7 +42,6 @@ pub const LibCInstallation = struct {
pub fn parse(
allocator: *Allocator,
libc_file: []const u8,
stderr: anytype,
) !LibCInstallation {
var self: LibCInstallation = .{};
@@ -65,7 +66,7 @@ pub const LibCInstallation = struct {
if (line.len == 0 or line[0] == '#') continue;
var line_it = std.mem.split(line, "=");
const name = line_it.next() orelse {
try stderr.print("missing equal sign after field name\n", .{});
log.err("missing equal sign after field name\n", .{});
return error.ParseError;
};
const value = line_it.rest();
@@ -84,31 +85,31 @@ pub const LibCInstallation = struct {
}
inline for (fields) |field, i| {
if (!found_keys[i].found) {
try stderr.print("missing field: {}\n", .{field.name});
log.err("missing field: {}\n", .{field.name});
return error.ParseError;
}
}
if (self.include_dir == null) {
try stderr.print("include_dir may not be empty\n", .{});
log.err("include_dir may not be empty\n", .{});
return error.ParseError;
}
if (self.sys_include_dir == null) {
try stderr.print("sys_include_dir may not be empty\n", .{});
log.err("sys_include_dir may not be empty\n", .{});
return error.ParseError;
}
if (self.crt_dir == null and !is_darwin) {
try stderr.print("crt_dir may not be empty for {}\n", .{@tagName(Target.current.os.tag)});
log.err("crt_dir may not be empty for {}\n", .{@tagName(Target.current.os.tag)});
return error.ParseError;
}
if (self.msvc_lib_dir == null and is_windows and !is_gnu) {
try stderr.print("msvc_lib_dir may not be empty for {}-{}\n", .{
log.err("msvc_lib_dir may not be empty for {}-{}\n", .{
@tagName(Target.current.os.tag),
@tagName(Target.current.abi),
});
return error.ParseError;
}
if (self.kernel32_lib_dir == null and is_windows and !is_gnu) {
try stderr.print("kernel32_lib_dir may not be empty for {}-{}\n", .{
log.err("kernel32_lib_dir may not be empty for {}-{}\n", .{
@tagName(Target.current.os.tag),
@tagName(Target.current.abi),
});

View File

@@ -615,12 +615,9 @@ const Stage2LibCInstallation = extern struct {
// ABI warning
export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error {
stderr_file = std.io.getStdErr();
stderr = stderr_file.outStream();
const libc_file = mem.spanZ(libc_file_z);
var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file, stderr) catch |err| switch (err) {
var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file) catch |err| switch (err) {
error.ParseError => return .SemanticAnalyzeFail,
error.DiskQuota => return .DiskQuota,
error.FileTooBig => return .FileTooBig,
error.InputOutput => return .FileSystem,
error.NoSpaceLeft => return .NoSpaceLeft,
@@ -629,7 +626,6 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [
error.SystemResources => return .SystemResources,
error.OperationAborted => return .OperationAborted,
error.WouldBlock => unreachable,
error.NotOpenForWriting => unreachable,
error.NotOpenForReading => unreachable,
error.Unexpected => return .Unexpected,
error.IsDir => return .IsDir,

View File

@@ -6324,10 +6324,18 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.
break :blk inner;
} else try parseCPrefixOpExpr(c, m, scope);
const builtin_call = try c.createBuiltinCall("@sizeOf", 1);
builtin_call.params()[0] = inner;
builtin_call.rparen_token = try appendToken(c, .RParen, ")");
return &builtin_call.base;
//(@import("std").meta.sizeof(dest, x))
const import_fn_call = try c.createBuiltinCall("@import", 1);
const std_node = try transCreateNodeStringLiteral(c, "\"std\"");
import_fn_call.params()[0] = std_node;
import_fn_call.rparen_token = try appendToken(c, .RParen, ")");
const inner_field_access = try transCreateNodeFieldAccess(c, &import_fn_call.base, "meta");
const outer_field_access = try transCreateNodeFieldAccess(c, inner_field_access, "sizeof");
const sizeof_call = try c.createCall(outer_field_access, 1);
sizeof_call.params()[0] = inner;
sizeof_call.rtoken = try appendToken(c, .RParen, ")");
return &sizeof_call.base;
},
.Keyword_alignof => {
// TODO this won't work if using <stdalign.h>'s