authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-09 12:17:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-09 12:17:23-04:00
log62065a9aea1c3c93cfea617403b7d5dc8344e36a
treeaeb127a713818b7c0310a92a1c8d29ee7c3d3626
parenta7346ea49f4d9b1af2d0babf67354b234a87fe42
signaturelock-open Commit is signed but in an unrecognized format.

translate-c: handle int to ptr and ptr to int casting

See #2451

2 files changed, 52 insertions(+), 0 deletions(-)

src/translate_c.cpp+38
......@@ -581,6 +581,33 @@ static bool qual_type_is_ptr(ZigClangQualType qt) {
581581 return ZigClangType_getTypeClass(ty) == ZigClangType_Pointer;
582582}
583583
584static bool qual_type_is_int(ZigClangQualType qt) {
585 const ZigClangType *ty = qual_type_canon(qt);
586 if (ZigClangType_getTypeClass(ty) != ZigClangType_Builtin)
587 return false;
588 const clang::BuiltinType *builtin_ty = reinterpret_cast<const clang::BuiltinType*>(ty);
589 switch (builtin_ty->getKind()) {
590 case clang::BuiltinType::Char_U:
591 case clang::BuiltinType::UChar:
592 case clang::BuiltinType::Char_S:
593 case clang::BuiltinType::Char8:
594 case clang::BuiltinType::SChar:
595 case clang::BuiltinType::UShort:
596 case clang::BuiltinType::UInt:
597 case clang::BuiltinType::ULong:
598 case clang::BuiltinType::ULongLong:
599 case clang::BuiltinType::Short:
600 case clang::BuiltinType::Int:
601 case clang::BuiltinType::Long:
602 case clang::BuiltinType::LongLong:
603 case clang::BuiltinType::UInt128:
604 case clang::BuiltinType::Int128:
605 return true;
606 default:
607 return false;
608 }
609}
610
584611static const clang::FunctionProtoType *qual_type_get_fn_proto(ZigClangQualType qt, bool *is_ptr) {
585612 const ZigClangType *ty = qual_type_canon(qt);
586613 *is_ptr = false;
......@@ -744,6 +771,17 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,
744771 if (qual_type_is_ptr(dest_type) && qual_type_is_ptr(src_type)) {
745772 return trans_c_ptr_cast(c, source_location, dest_type, src_type, expr);
746773 }
774 if (qual_type_is_int(dest_type) && qual_type_is_ptr(src_type)) {
775 AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
776 addr_node->data.fn_call_expr.params.append(expr);
777 return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), addr_node);
778 }
779 if (qual_type_is_int(src_type) && qual_type_is_ptr(dest_type)) {
780 AstNode *ptr_node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
781 ptr_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
782 ptr_node->data.fn_call_expr.params.append(expr);
783 return ptr_node;
784 }
747785 // TODO: maybe widen to increase size
748786 // TODO: maybe bitcast to change sign
749787 // TODO: maybe truncate to reduce size
test/translate_c.zig+14
......@@ -2,6 +2,20 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.TranslateCContext) void {
5 cases.add("casting pointers to ints and ints to pointers",
6 \\void foo(void);
7 \\void bar(void) {
8 \\ void *func_ptr = foo;
9 \\ void (*typed_func_ptr)(void) = (void (*)(void)) (unsigned long) func_ptr;
10 \\}
11 ,
12 \\pub extern fn foo() void;
13 \\pub fn bar() void {
14 \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
15 \\ var typed_func_ptr: ?extern fn() void = @intToPtr(?extern fn() void, c_ulong(@ptrToInt(func_ptr)));
16 \\}
17 );
18
519 if (builtin.os != builtin.Os.windows) {
620 // Windows treats this as an enum with type c_int
721 cases.add("big negative enum init values when C ABI supports long long enums",