Translate C: Allow casting literal ints to pointers
This commit is contained in:
parent
7b5fb79b5b
commit
d7902707bc
@ -5479,18 +5479,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
|||||||
.LParen => {
|
.LParen => {
|
||||||
const inner_node = try parseCExpr(c, it, source, source_loc, scope);
|
const inner_node = try parseCExpr(c, it, source, source_loc, scope);
|
||||||
|
|
||||||
if (it.next().?.id != .RParen) {
|
const next_id = it.next().?.id;
|
||||||
|
if (next_id != .RParen) {
|
||||||
const first_tok = it.list.at(0);
|
const first_tok = it.list.at(0);
|
||||||
try failDecl(
|
try failDecl(
|
||||||
c,
|
c,
|
||||||
source_loc,
|
source_loc,
|
||||||
source[first_tok.start..first_tok.end],
|
source[first_tok.start..first_tok.end],
|
||||||
"unable to translate C expr: expected ')'' here",
|
"unable to translate C expr: expected ')'' instead got: {}",
|
||||||
.{},
|
.{@tagName(next_id)},
|
||||||
);
|
);
|
||||||
return error.ParseError;
|
return error.ParseError;
|
||||||
}
|
}
|
||||||
var saw_l_paren = false;
|
var saw_l_paren = false;
|
||||||
|
var saw_integer_literal = false;
|
||||||
switch (it.peek().?.id) {
|
switch (it.peek().?.id) {
|
||||||
// (type)(to_cast)
|
// (type)(to_cast)
|
||||||
.LParen => {
|
.LParen => {
|
||||||
@ -5499,6 +5501,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
|||||||
},
|
},
|
||||||
// (type)identifier
|
// (type)identifier
|
||||||
.Identifier => {},
|
.Identifier => {},
|
||||||
|
// (type)integer
|
||||||
|
.IntegerLiteral => {
|
||||||
|
saw_integer_literal = true;
|
||||||
|
},
|
||||||
else => return inner_node,
|
else => return inner_node,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5519,6 +5525,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
|||||||
return error.ParseError;
|
return error.ParseError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (saw_integer_literal) {
|
||||||
|
// @intToPtr(dest, x)
|
||||||
|
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 (@typeInfo(@TypeOf(x)) == .Pointer)
|
//( if (@typeInfo(@TypeOf(x)) == .Pointer)
|
||||||
// @ptrCast(dest, @alignCast(@alignOf(dest.Child), x))
|
// @ptrCast(dest, @alignCast(@alignOf(dest.Child), x))
|
||||||
//else if (@typeInfo(@TypeOf(x)) == .Integer and @typeInfo(dest) == .Pointer))
|
//else if (@typeInfo(@TypeOf(x)) == .Integer and @typeInfo(dest) == .Pointer))
|
||||||
@ -5750,19 +5765,24 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
|||||||
// hack to get zig fmt to render a comma in builtin calls
|
// hack to get zig fmt to render a comma in builtin calls
|
||||||
_ = try appendToken(c, .Comma, ",");
|
_ = try appendToken(c, .Comma, ",");
|
||||||
|
|
||||||
const ptr_kind = blk: {
|
// * token
|
||||||
// * token
|
_ = it.prev();
|
||||||
_ = it.prev();
|
// last token of `node`
|
||||||
// last token of `node`
|
const prev_id = it.prev().?.id;
|
||||||
const prev_id = it.prev().?.id;
|
_ = it.next();
|
||||||
_ = it.next();
|
_ = it.next();
|
||||||
_ = it.next();
|
|
||||||
break :blk if (prev_id == .Keyword_void) .Asterisk else Token.Id.Identifier;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ptr = try transCreateNodePtrType(c, false, false, ptr_kind);
|
if (prev_id == .Keyword_void) {
|
||||||
ptr.rhs = node;
|
const ptr = try transCreateNodePtrType(c, false, false, .Asterisk);
|
||||||
return &ptr.base;
|
ptr.rhs = node;
|
||||||
|
const optional_node = try transCreateNodePrefixOp(c, .OptionalType, .QuestionMark, "?");
|
||||||
|
optional_node.rhs = &ptr.base;
|
||||||
|
return &optional_node.base;
|
||||||
|
} else {
|
||||||
|
const ptr = try transCreateNodePtrType(c, false, false, Token.Id.Identifier);
|
||||||
|
ptr.rhs = node;
|
||||||
|
return &ptr.base;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// expr * expr
|
// expr * expr
|
||||||
op_token = try appendToken(c, .Asterisk, "*");
|
op_token = try appendToken(c, .Asterisk, "*");
|
||||||
|
@ -2668,11 +2668,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\#define FOO(bar) baz((void *)(baz))
|
\\#define FOO(bar) baz((void *)(baz))
|
||||||
\\#define BAR (void*) a
|
\\#define BAR (void*) a
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
\\pub inline fn FOO(bar: var) @TypeOf(baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, @alignCast(@alignOf(*c_void.Child), baz)) else if (@typeInfo(@TypeOf(baz)) == .Int and @typeInfo(*c_void) == .Pointer) @intToPtr(*c_void, baz) else @as(*c_void, baz)))) {
|
\\pub inline fn FOO(bar: var) @TypeOf(baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(?*c_void, @alignCast(@alignOf(?*c_void.Child), baz)) else if (@typeInfo(@TypeOf(baz)) == .Int and @typeInfo(?*c_void) == .Pointer) @intToPtr(?*c_void, baz) else @as(?*c_void, baz)))) {
|
||||||
\\ return baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, @alignCast(@alignOf(*c_void.Child), baz)) else if (@typeInfo(@TypeOf(baz)) == .Int and @typeInfo(*c_void) == .Pointer) @intToPtr(*c_void, baz) else @as(*c_void, baz)));
|
\\ return baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(?*c_void, @alignCast(@alignOf(?*c_void.Child), baz)) else if (@typeInfo(@TypeOf(baz)) == .Int and @typeInfo(?*c_void) == .Pointer) @intToPtr(?*c_void, baz) else @as(?*c_void, baz)));
|
||||||
\\}
|
\\}
|
||||||
,
|
,
|
||||||
\\pub const BAR = (if (@typeInfo(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, @alignCast(@alignOf(*c_void.Child), a)) else if (@typeInfo(@TypeOf(a)) == .Int and @typeInfo(*c_void) == .Pointer) @intToPtr(*c_void, a) else @as(*c_void, a));
|
\\pub const BAR = (if (@typeInfo(@TypeOf(a)) == .Pointer) @ptrCast(?*c_void, @alignCast(@alignOf(?*c_void.Child), a)) else if (@typeInfo(@TypeOf(a)) == .Int and @typeInfo(?*c_void) == .Pointer) @intToPtr(?*c_void, a) else @as(?*c_void, a));
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add("macro conditional operator",
|
cases.add("macro conditional operator",
|
||||||
@ -2894,4 +2894,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ return (if (@typeInfo(@TypeOf(dpy)) == .Pointer) @ptrCast(_XPrivDisplay, @alignCast(@alignOf(_XPrivDisplay.Child), dpy)) else if (@typeInfo(@TypeOf(dpy)) == .Int and @typeInfo(_XPrivDisplay) == .Pointer) @intToPtr(_XPrivDisplay, dpy) else @as(_XPrivDisplay, dpy)).*.default_screen;
|
\\ return (if (@typeInfo(@TypeOf(dpy)) == .Pointer) @ptrCast(_XPrivDisplay, @alignCast(@alignOf(_XPrivDisplay.Child), dpy)) else if (@typeInfo(@TypeOf(dpy)) == .Int and @typeInfo(_XPrivDisplay) == .Pointer) @intToPtr(_XPrivDisplay, dpy) else @as(_XPrivDisplay, dpy)).*.default_screen;
|
||||||
\\}
|
\\}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cases.add("Cast from integer literals to poiter",
|
||||||
|
\\#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)
|
||||||
|
\\
|
||||||
|
, &[_][]const u8{
|
||||||
|
\\pub const NULL = @intToPtr(?*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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user