Merge pull request #5046 from Vexu/translate-c

Translate-c correct invalid shortcut
This commit is contained in:
Vexu 2020-04-15 18:06:38 +03:00 committed by GitHub
commit 0276d9ddc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 92 additions and 70 deletions

View File

@ -205,7 +205,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
better_capacity += better_capacity / 2 + 8;
if (better_capacity >= new_capacity) break;
}
const new_memory = try self.allocator.realloc(self.allocatedSlice(), better_capacity);
self.items.ptr = new_memory.ptr;
self.capacity = new_memory.len;
@ -250,7 +250,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
if (self.items.len == 0) return null;
return self.pop();
}
// For a nicer API, `items.len` is the length, not the capacity.
// This requires "unsafe" slicing.
fn allocatedSlice(self: Self) Slice {
@ -448,16 +448,16 @@ test "std.ArrayList(u8) implements outStream" {
}
test "std.ArrayList.shrink still sets length on error.OutOfMemory" {
// use an arena allocator to make sure realloc returns error.OutOfMemory
var arena = std.heap.ArenaAllocator.init(testing.allocator);
defer arena.deinit();
// use an arena allocator to make sure realloc returns error.OutOfMemory
var arena = std.heap.ArenaAllocator.init(testing.allocator);
defer arena.deinit();
var list = ArrayList(i32).init(&arena.allocator);
var list = ArrayList(i32).init(&arena.allocator);
try list.append(1);
try list.append(2);
try list.append(3);
try list.append(1);
try list.append(2);
try list.append(3);
list.shrink(1);
testing.expect(list.items.len == 1);
list.shrink(1);
testing.expect(list.items.len == 1);
}

View File

@ -1467,7 +1467,6 @@ pub const Int = struct {
r.swap(&x);
}
};
// Storage must live for the lifetime of the returned value

View File

@ -2584,7 +2584,7 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
}
}
pub const FStatAtError = FStatError || error{NameTooLong, FileNotFound};
pub const FStatAtError = FStatError || error{ NameTooLong, FileNotFound };
pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat {
const pathname_c = try toPosixPath(pathname);

View File

@ -42,4 +42,4 @@ pub extern "gdi32" fn ChoosePixelFormat(
pub extern "gdi32" fn SwapBuffers(hdc: ?HDC) callconv(.Stdcall) bool;
pub extern "gdi32" fn wglCreateContext(hdc: ?HDC) callconv(.Stdcall) ?HGLRC;
pub extern "gdi32" fn wglMakeCurrent(hdc: ?HDC, hglrc: ?HGLRC) callconv(.Stdcall) bool;
pub extern "gdi32" fn wglMakeCurrent(hdc: ?HDC, hglrc: ?HGLRC) callconv(.Stdcall) bool;

View File

@ -169,4 +169,4 @@ pub extern "user32" fn GetMessageA(
pub extern "user32" fn TranslateMessage(lpMsg: *const MSG) callconv(.Stdcall) bool;
pub extern "user32" fn DispatchMessageA(lpMsg: *const MSG) callconv(.Stdcall) LRESULT;
pub extern "user32" fn PostQuitMessage(nExitCode: i32) callconv(.Stdcall) void;
pub extern "user32" fn PostQuitMessage(nExitCode: i32) callconv(.Stdcall) void;

View File

@ -387,7 +387,7 @@ test "zig fmt: correctly space struct fields with doc comments" {
\\ c: u8,
\\};
\\
,
,
\\pub const S = struct {
\\ /// A
\\ a: u8,

View File

@ -903,13 +903,14 @@ fn enumToString(value: var, type_name: []const u8) ![]const u8 {
if (e.is_exhaustive) {
return std.fmt.allocPrint(std.heap.c_allocator, ".{}", .{@tagName(value)});
} else {
return std.fmt.allocPrint(std.heap.c_allocator,
return std.fmt.allocPrint(
std.heap.c_allocator,
"@intToEnum({}, {})",
.{type_name, @enumToInt(value)}
.{ type_name, @enumToInt(value) },
);
}
},
else => unreachable
else => unreachable,
}
}
@ -1136,7 +1137,7 @@ const Stage2Target = extern struct {
\\
, .{
try enumToString(target.os.version_range.windows.min, "Target.Os.WindowsVersion"),
try enumToString(target.os.version_range.windows.max, "Target.Os.WindowsVersion")
try enumToString(target.os.version_range.windows.max, "Target.Os.WindowsVersion"),
}),
}
try os_builtin_str_buffer.appendSlice("};\n");

View File

@ -274,7 +274,7 @@ pub fn translate(
errdefer tree_arena.deinit();
const tree = try tree_arena.allocator.create(ast.Tree);
tree.* = ast.Tree{
tree.* = .{
.source = undefined, // need to use toOwnedSlice later
.root_node = undefined,
.arena_allocator = tree_arena,
@ -644,7 +644,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
};
const node = try c.a().create(ast.Node.VarDecl);
node.* = ast.Node.VarDecl{
node.* = .{
.doc_comments = null,
.visib_token = visib_tok,
.thread_local_token = thread_local_token,
@ -3479,7 +3479,7 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
// we can perform the log2 now.
const cast_bit_width = math.log2_int(u64, int_bit_width);
const node = try rp.c.a().create(ast.Node.IntegerLiteral);
node.* = ast.Node.IntegerLiteral{
node.* = .{
.token = try appendTokenFmt(rp.c, .Identifier, "u{}", .{cast_bit_width}),
};
return &node.base;
@ -3502,7 +3502,7 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
const import_fn_call = try transCreateNodeBuiltinFnCall(rp.c, "@import");
const std_token = try appendToken(rp.c, .StringLiteral, "\"std\"");
const std_node = try rp.c.a().create(ast.Node.StringLiteral);
std_node.* = ast.Node.StringLiteral{
std_node.* = .{
.token = std_token,
};
try import_fn_call.params.push(&std_node.base);
@ -3783,7 +3783,7 @@ fn transCreateNodePrefixOp(
bytes: []const u8,
) !*ast.Node.PrefixOp {
const node = try c.a().create(ast.Node.PrefixOp);
node.* = ast.Node.PrefixOp{
node.* = .{
.op_token = try appendToken(c, op_tok_id, bytes),
.op = op,
.rhs = undefined, // translate and set afterward
@ -3980,7 +3980,7 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp {
_ = try appendToken(c, .LBrace, "{");
const node = try c.a().create(ast.Node.SuffixOp);
node.* = ast.Node.SuffixOp{
node.* = .{
.lhs = .{ .node = ty },
.op = .{
.ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
@ -3993,7 +3993,7 @@ fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.Suffix
fn transCreateNodeStructInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp {
_ = try appendToken(c, .LBrace, "{");
const node = try c.a().create(ast.Node.SuffixOp);
node.* = ast.Node.SuffixOp{
node.* = .{
.lhs = .{ .node = ty },
.op = .{
.StructInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
@ -4306,7 +4306,7 @@ fn transCreateNodeShiftOp(
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
const node = try rp.c.a().create(ast.Node.InfixOp);
node.* = ast.Node.InfixOp{
node.* = .{
.op_token = op_token,
.lhs = lhs,
.op = op,
@ -4626,8 +4626,7 @@ fn finishTransFnProto(
const type_node = try transQualType(rp, param_qt, source_loc);
const param_node = try rp.c.a().create(ast.Node.ParamDecl);
param_node.* = ast.Node.ParamDecl{
.base = ast.Node{ .id = ast.Node.Id.ParamDecl },
param_node.* = .{
.doc_comments = null,
.comptime_token = null,
.noalias_token = noalias_tok,
@ -4648,8 +4647,7 @@ fn finishTransFnProto(
}
const var_arg_node = try rp.c.a().create(ast.Node.ParamDecl);
var_arg_node.* = ast.Node.ParamDecl{
.base = ast.Node{ .id = ast.Node.Id.ParamDecl },
var_arg_node.* = .{
.doc_comments = null,
.comptime_token = null,
.noalias_token = null,
@ -4774,14 +4772,12 @@ pub fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comp
const semi_tok = try appendToken(c, .Semicolon, ";");
const msg_node = try c.a().create(ast.Node.StringLiteral);
msg_node.* = ast.Node.StringLiteral{
.base = ast.Node{ .id = ast.Node.Id.StringLiteral },
msg_node.* = .{
.token = msg_tok,
};
const call_node = try c.a().create(ast.Node.BuiltinCall);
call_node.* = ast.Node.BuiltinCall{
.base = ast.Node{ .id = ast.Node.Id.BuiltinCall },
call_node.* = .{
.builtin_token = builtin_tok,
.params = ast.Node.BuiltinCall.ParamList.init(c.a()),
.rparen_token = rparen_tok,
@ -4789,8 +4785,7 @@ pub fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comp
try call_node.params.push(&msg_node.base);
const var_decl_node = try c.a().create(ast.Node.VarDecl);
var_decl_node.* = ast.Node.VarDecl{
.base = ast.Node{ .id = ast.Node.Id.VarDecl },
var_decl_node.* = .{
.doc_comments = null,
.visib_token = pub_tok,
.thread_local_token = null,
@ -4825,7 +4820,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
const new_token = try c.tree.tokens.addOne();
errdefer c.tree.tokens.shrink(token_index);
new_token.* = Token{
new_token.* = .{
.id = token_id,
.start = start_index,
.end = end_index,
@ -5523,36 +5518,70 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
return error.ParseError;
}
const lparen = try appendToken(c, .LParen, "(");
if (saw_integer_literal) {
// @intToPtr(dest, x)
//( if (@typeInfo(dest) == .Pointer))
// @intToPtr(dest, x)
//else
// @as(dest, x) )
const if_node = try transCreateNodeIf(c);
const type_info_node = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
try type_info_node.params.push(inner_node);
type_info_node.rparen_token = try appendToken(c, .LParen, ")");
const cmp_node = try c.a().create(ast.Node.InfixOp);
cmp_node.* = .{
.op_token = try appendToken(c, .EqualEqual, "=="),
.lhs = &type_info_node.base,
.op = .EqualEqual,
.rhs = try transCreateNodeEnumLiteral(c, "Pointer"),
};
if_node.condition = &cmp_node.base;
_ = try appendToken(c, .RParen, ")");
const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr");
try int_to_ptr.params.push(inner_node);
try int_to_ptr.params.push(node_to_cast);
int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");
return &int_to_ptr.base;
if_node.body = &int_to_ptr.base;
const else_node = try transCreateNodeElse(c);
if_node.@"else" = else_node;
const as_node = try transCreateNodeBuiltinFnCall(c, "@as");
try as_node.params.push(inner_node);
try as_node.params.push(node_to_cast);
as_node.rparen_token = try appendToken(c, .RParen, ")");
else_node.body = &as_node.base;
const group_node = try c.a().create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = lparen,
.expr = &if_node.base,
.rparen = try appendToken(c, .RParen, ")"),
};
return &group_node.base;
}
//( if (@typeInfo(@TypeOf(x)) == .Pointer)
// @ptrCast(dest, @alignCast(@alignOf(dest.Child), x))
//else if (@typeInfo(@TypeOf(x)) == .Integer and @typeInfo(dest) == .Pointer))
//else if (@typeInfo(@TypeOf(x)) == .Int and @typeInfo(dest) == .Pointer))
// @intToPtr(dest, x)
//else
// @as(dest, x) )
const lparen = try appendToken(c, .LParen, "(");
const if_1 = try transCreateNodeIf(c);
const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
const type_info_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
try type_id_1.params.push(&type_of_1.base);
try type_info_1.params.push(&type_of_1.base);
try type_of_1.params.push(node_to_cast);
type_of_1.rparen_token = try appendToken(c, .RParen, ")");
type_id_1.rparen_token = try appendToken(c, .RParen, ")");
type_info_1.rparen_token = try appendToken(c, .RParen, ")");
const cmp_1 = try c.a().create(ast.Node.InfixOp);
cmp_1.* = .{
.op_token = try appendToken(c, .EqualEqual, "=="),
.lhs = &type_id_1.base,
.lhs = &type_info_1.base,
.op = .EqualEqual,
.rhs = try transCreateNodeEnumLiteral(c, "Pointer"),
};
@ -5590,17 +5619,17 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
if_1.@"else" = else_1;
const if_2 = try transCreateNodeIf(c);
const type_id_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
const type_info_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
try type_id_2.params.push(&type_of_2.base);
try type_info_2.params.push(&type_of_2.base);
try type_of_2.params.push(node_to_cast);
type_of_2.rparen_token = try appendToken(c, .RParen, ")");
type_id_2.rparen_token = try appendToken(c, .RParen, ")");
type_info_2.rparen_token = try appendToken(c, .RParen, ")");
const cmp_2 = try c.a().create(ast.Node.InfixOp);
cmp_2.* = .{
.op_token = try appendToken(c, .EqualEqual, "=="),
.lhs = &type_id_2.base,
.lhs = &type_info_2.base,
.op = .EqualEqual,
.rhs = try transCreateNodeEnumLiteral(c, "Int"),
};
@ -5612,13 +5641,13 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.op = .BoolAnd,
.rhs = undefined,
};
const type_id_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
try type_id_3.params.push(inner_node);
type_id_3.rparen_token = try appendToken(c, .LParen, ")");
const type_info_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
try type_info_3.params.push(inner_node);
type_info_3.rparen_token = try appendToken(c, .LParen, ")");
const cmp_3 = try c.a().create(ast.Node.InfixOp);
cmp_3.* = .{
.op_token = try appendToken(c, .EqualEqual, "=="),
.lhs = &type_id_3.base,
.lhs = &type_info_3.base,
.op = .EqualEqual,
.rhs = try transCreateNodeEnumLiteral(c, "Pointer"),
};

View File

@ -162,7 +162,7 @@ test "for copies its payload" {
test "for on slice with allowzero ptr" {
const S = struct {
fn doTheTest(slice: []const u8) void {
var ptr = @ptrCast([*]const allowzero u8, slice.ptr)[0..slice.len];
var ptr = @ptrCast([*]allowzero const u8, slice.ptr)[0..slice.len];
for (ptr) |x, i| expect(x == i + 1);
for (ptr) |*x, i| expect(x.* == i + 1);
}

View File

@ -2879,7 +2879,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub const FOO = 0x61626364;
});
cases.add("Make sure casts are grouped",
\\typedef struct
\\{
@ -2895,22 +2895,15 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
cases.add("Cast from integer literals to poiter",
cases.add("macro integer literal casts",
\\#define NULL ((void*)0)
\\#define GPIO_0_MEM_MAP ((unsigned*)0x8000)
\\#define GPIO_1_MEM_MAP ((unsigned*)0x8004)
\\#define GPIO_2_MEM_MAP ((unsigned*)0x8008)
\\
\\#define FOO ((int)0x8000)
, &[_][]const u8{
\\pub const NULL = @intToPtr(?*c_void, 0);
\\pub const NULL = (if (@typeInfo(?*c_void) == .Pointer) @intToPtr(?*c_void, 0) else @as(?*c_void, 0));
,
\\pub const GPIO_0_MEM_MAP = @intToPtr([*c]c_uint, 0x8000);
,
\\pub const GPIO_1_MEM_MAP = @intToPtr([*c]c_uint, 0x8004);
,
\\pub const GPIO_2_MEM_MAP = @intToPtr([*c]c_uint, 0x8008);
\\pub const FOO = (if (@typeInfo(c_int) == .Pointer) @intToPtr(c_int, 0x8000) else @as(c_int, 0x8000));
});
if (std.Target.current.abi == .msvc) {
cases.add("nameless struct fields",
\\typedef struct NAMED