mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
c-to-zig: handle UO_Deref
This commit is contained in:
parent
6ffaf4c2e2
commit
5029322aa1
@ -625,7 +625,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||
fprintf(ar->f, "@");
|
||||
}
|
||||
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
|
||||
bool grouped = (fn_ref_node->type != NodeTypeBinOpExpr);
|
||||
bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr);
|
||||
render_node_extra(ar, fn_ref_node, grouped);
|
||||
fprintf(ar->f, "(");
|
||||
for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
|
||||
|
||||
@ -350,6 +350,21 @@ static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location,
|
||||
return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr);
|
||||
}
|
||||
|
||||
static bool qual_type_is_fn_ptr(Context *c, const QualType &qt) {
|
||||
const Type *ty = qt.getTypePtr();
|
||||
if (ty->getTypeClass() != Type::Pointer) {
|
||||
return false;
|
||||
}
|
||||
const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
|
||||
QualType child_qt = pointer_ty->getPointeeType();
|
||||
const Type *child_ty = child_qt.getTypePtr();
|
||||
if (child_ty->getTypeClass() != Type::Paren) {
|
||||
return false;
|
||||
}
|
||||
const ParenType *paren_ty = static_cast<const ParenType *>(child_ty);
|
||||
return paren_ty->getInnerType().getTypePtr()->getTypeClass() == Type::FunctionProto;
|
||||
}
|
||||
|
||||
static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {
|
||||
const Type *ty = qt.getTypePtr();
|
||||
switch (ty->getTypeClass()) {
|
||||
@ -1575,8 +1590,14 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc
|
||||
emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_AddrOf");
|
||||
return nullptr;
|
||||
case UO_Deref:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Deref");
|
||||
return nullptr;
|
||||
{
|
||||
bool is_fn_ptr = qual_type_is_fn_ptr(c, stmt->getSubExpr()->getType());
|
||||
AstNode *value_node = trans_expr(c, result_used, block, stmt->getSubExpr(), TransRValue);
|
||||
if (is_fn_ptr)
|
||||
return value_node;
|
||||
AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);
|
||||
return trans_create_node_prefix_op(c, PrefixOpDereference, unwrapped);
|
||||
}
|
||||
case UO_Plus:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus");
|
||||
return nullptr;
|
||||
@ -1919,10 +1940,20 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {
|
||||
|
||||
static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, CallExpr *stmt) {
|
||||
AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
|
||||
node->data.fn_call_expr.fn_ref_expr = trans_expr(c, true, block, stmt->getCallee(), TransRValue);
|
||||
if (node->data.fn_call_expr.fn_ref_expr == nullptr)
|
||||
|
||||
AstNode *callee_raw_node = trans_expr(c, true, block, stmt->getCallee(), TransRValue);
|
||||
if (callee_raw_node == nullptr)
|
||||
return nullptr;
|
||||
|
||||
AstNode *callee_node;
|
||||
if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) {
|
||||
callee_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, callee_raw_node);
|
||||
} else {
|
||||
callee_node = callee_raw_node;
|
||||
}
|
||||
|
||||
node->data.fn_call_expr.fn_ref_expr = callee_node;
|
||||
|
||||
unsigned num_args = stmt->getNumArgs();
|
||||
Expr **args = stmt->getArgs();
|
||||
for (unsigned i = 0; i < num_args; i += 1) {
|
||||
|
||||
@ -203,13 +203,13 @@ pub fn addCases(cases: &tests.ParseCContext) {
|
||||
\\pub extern var fn_ptr: ?extern fn();
|
||||
,
|
||||
\\pub inline fn foo() {
|
||||
\\ ??fn_ptr()
|
||||
\\ (??fn_ptr)()
|
||||
\\}
|
||||
,
|
||||
\\pub extern var fn_ptr2: ?extern fn(c_int, f32) -> u8;
|
||||
,
|
||||
\\pub inline fn bar(arg0: c_int, arg1: f32) -> u8 {
|
||||
\\ ??fn_ptr2(arg0, arg1)
|
||||
\\ (??fn_ptr2)(arg0, arg1)
|
||||
\\}
|
||||
);
|
||||
|
||||
@ -831,6 +831,32 @@ pub fn addCases(cases: &tests.ParseCContext) {
|
||||
\\ };
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.addC("deref function pointer",
|
||||
\\void foo(void) {}
|
||||
\\void bar(void) {
|
||||
\\ void(*f)(void) = foo;
|
||||
\\ f();
|
||||
\\ (*(f))();
|
||||
\\}
|
||||
,
|
||||
\\export fn foo() {}
|
||||
\\export fn bar() {
|
||||
\\ var f: ?extern fn() = foo;
|
||||
\\ (??f)();
|
||||
\\ (??f)();
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.addC("normal deref",
|
||||
\\void foo(int *x) {
|
||||
\\ *x = 1;
|
||||
\\}
|
||||
,
|
||||
\\export fn foo(x: ?&c_int) {
|
||||
\\ (*(??x)) = 1;
|
||||
\\}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user