| author | |
| committer | |
| log | 9c4dc7b1bb79b2e1cf5a88d99b9e187640426769 |
| tree | 5f964c24ade38e7c16ccef3b655d7919ef609d5e |
| parent | 3e93dce0a12e8b09f2de30276364d9ee18c6ada0 |
| parent | cb4c488cbd1e02b88ca8e7466a0945691f06d4fd |
| signature |
Translate-c improvements5 files changed, 67 insertions(+), 12 deletions(-)
src-self-hosted/clang.zig+1| ... | ... | @@ -765,6 +765,7 @@ pub extern fn ZigClangTagDecl_isThisDeclarationADefinition(self: *const ZigClang |
| 765 | 765 | pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl; |
| 766 | 766 | pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl; |
| 767 | 767 | pub extern fn ZigClangFieldDecl_getCanonicalDecl(field_decl: ?*const struct_ZigClangFieldDecl) ?*const struct_ZigClangFieldDecl; |
| 768 | pub extern fn ZigClangFieldDecl_getAlignedAttribute(field_decl: ?*const struct_ZigClangFieldDecl, *const ZigClangASTContext) c_uint; | |
| 768 | 769 | pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl; |
| 769 | 770 | pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl; |
| 770 | 771 | pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl; |
src-self-hosted/translate_c.zig+40-7| ... | ... | @@ -560,7 +560,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 560 | 560 | |
| 561 | 561 | // TODO https://github.com/ziglang/zig/issues/3756 |
| 562 | 562 | // TODO https://github.com/ziglang/zig/issues/1802 |
| 563 | const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.a(), "_{}", .{var_name}) else var_name; | |
| 563 | const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{var_name, c.getMangle()}) else var_name; | |
| 564 | 564 | const var_decl_loc = ZigClangVarDecl_getLocation(var_decl); |
| 565 | 565 | |
| 566 | 566 | const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl); |
| ... | ... | @@ -632,7 +632,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 632 | 632 | const align_expr = blk: { |
| 633 | 633 | const alignment = ZigClangVarDecl_getAlignedAttribute(var_decl, rp.c.clang_context); |
| 634 | 634 | if (alignment != 0) { |
| 635 | _ = try appendToken(rp.c, .Keyword_linksection, "align"); | |
| 635 | _ = try appendToken(rp.c, .Keyword_align, "align"); | |
| 636 | 636 | _ = try appendToken(rp.c, .LParen, "("); |
| 637 | 637 | // Clang reports the alignment in bits |
| 638 | 638 | const expr = try transCreateNodeInt(rp.c, alignment / 8); |
| ... | ... | @@ -677,7 +677,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l |
| 677 | 677 | |
| 678 | 678 | // TODO https://github.com/ziglang/zig/issues/3756 |
| 679 | 679 | // TODO https://github.com/ziglang/zig/issues/1802 |
| 680 | const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "_{}", .{typedef_name}) else typedef_name; | |
| 680 | const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{typedef_name, c.getMangle()}) else typedef_name; | |
| 681 | 681 | |
| 682 | 682 | if (mem.eql(u8, checked_name, "uint8_t")) |
| 683 | 683 | return transTypeDefAsBuiltin(c, typedef_decl, "u8") |
| ... | ... | @@ -827,6 +827,20 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 827 | 827 | else => |e| return e, |
| 828 | 828 | }; |
| 829 | 829 | |
| 830 | const align_expr = blk: { | |
| 831 | const alignment = ZigClangFieldDecl_getAlignedAttribute(field_decl, rp.c.clang_context); | |
| 832 | if (alignment != 0) { | |
| 833 | _ = try appendToken(rp.c, .Keyword_align, "align"); | |
| 834 | _ = try appendToken(rp.c, .LParen, "("); | |
| 835 | // Clang reports the alignment in bits | |
| 836 | const expr = try transCreateNodeInt(rp.c, alignment / 8); | |
| 837 | _ = try appendToken(rp.c, .RParen, ")"); | |
| 838 | ||
| 839 | break :blk expr; | |
| 840 | } | |
| 841 | break :blk null; | |
| 842 | }; | |
| 843 | ||
| 830 | 844 | const field_node = try c.a().create(ast.Node.ContainerField); |
| 831 | 845 | field_node.* = .{ |
| 832 | 846 | .doc_comments = null, |
| ... | ... | @@ -834,7 +848,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 834 | 848 | .name_token = field_name, |
| 835 | 849 | .type_expr = field_type, |
| 836 | 850 | .value_expr = null, |
| 837 | .align_expr = null, | |
| 851 | .align_expr = align_expr, | |
| 838 | 852 | }; |
| 839 | 853 | |
| 840 | 854 | if (is_anon) { |
| ... | ... | @@ -4607,7 +4621,7 @@ fn finishTransFnProto( |
| 4607 | 4621 | if (fn_decl) |decl| { |
| 4608 | 4622 | const alignment = ZigClangFunctionDecl_getAlignedAttribute(decl, rp.c.clang_context); |
| 4609 | 4623 | if (alignment != 0) { |
| 4610 | _ = try appendToken(rp.c, .Keyword_linksection, "align"); | |
| 4624 | _ = try appendToken(rp.c, .Keyword_align, "align"); | |
| 4611 | 4625 | _ = try appendToken(rp.c, .LParen, "("); |
| 4612 | 4626 | // Clang reports the alignment in bits |
| 4613 | 4627 | const expr = try transCreateNodeInt(rp.c, alignment / 8); |
| ... | ... | @@ -4857,7 +4871,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 4857 | 4871 | const name = try c.str(raw_name); |
| 4858 | 4872 | // TODO https://github.com/ziglang/zig/issues/3756 |
| 4859 | 4873 | // TODO https://github.com/ziglang/zig/issues/1802 |
| 4860 | const mangled_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.a(), "_{}", .{name}) else name; | |
| 4874 | const mangled_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{name, c.getMangle()}) else name; | |
| 4861 | 4875 | if (scope.containsNow(mangled_name)) { |
| 4862 | 4876 | continue; |
| 4863 | 4877 | } |
| ... | ... | @@ -5437,7 +5451,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5437 | 5451 | |
| 5438 | 5452 | //if (@typeInfo(@TypeOf(x)) == .Pointer) |
| 5439 | 5453 | // @ptrCast(dest, x) |
| 5440 | //else if (@typeInfo(@TypeOf(x)) == .Integer) | |
| 5454 | //else if (@typeInfo(@TypeOf(x)) == .Int and @typeInfo(dest) == .Pointer) | |
| 5441 | 5455 | // @intToPtr(dest, x) |
| 5442 | 5456 | //else |
| 5443 | 5457 | // @as(dest, x) |
| ... | ... | @@ -5487,6 +5501,25 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5487 | 5501 | .rhs = try transCreateNodeEnumLiteral(c, "Int"), |
| 5488 | 5502 | }; |
| 5489 | 5503 | if_2.condition = &cmp_2.base; |
| 5504 | const cmp_4 = try c.a().create(ast.Node.InfixOp); | |
| 5505 | cmp_4.* = .{ | |
| 5506 | .op_token = try appendToken(c, .Keyword_and, "and"), | |
| 5507 | .lhs = &cmp_2.base, | |
| 5508 | .op = .BoolAnd, | |
| 5509 | .rhs = undefined, | |
| 5510 | }; | |
| 5511 | const type_id_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); | |
| 5512 | try type_id_3.params.push(inner_node); | |
| 5513 | type_id_3.rparen_token = try appendToken(c, .LParen, ")"); | |
| 5514 | const cmp_3 = try c.a().create(ast.Node.InfixOp); | |
| 5515 | cmp_3.* = .{ | |
| 5516 | .op_token = try appendToken(c, .EqualEqual, "=="), | |
| 5517 | .lhs = &type_id_3.base, | |
| 5518 | .op = .EqualEqual, | |
| 5519 | .rhs = try transCreateNodeEnumLiteral(c, "Pointer"), | |
| 5520 | }; | |
| 5521 | cmp_4.rhs = &cmp_3.base; | |
| 5522 | if_2.condition = &cmp_4.base; | |
| 5490 | 5523 | else_1.body = &if_2.base; |
| 5491 | 5524 | _ = try appendToken(c, .RParen, ")"); |
| 5492 | 5525 |
src/zig_clang.cpp+10| ... | ... | @@ -1615,6 +1615,16 @@ unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangVarDecl *self, |
| 1615 | 1615 | return 0; |
| 1616 | 1616 | } |
| 1617 | 1617 | |
| 1618 | unsigned ZigClangFieldDecl_getAlignedAttribute(const struct ZigClangFieldDecl *self, const ZigClangASTContext* ctx) { | |
| 1619 | auto casted_self = reinterpret_cast<const clang::FieldDecl *>(self); | |
| 1620 | auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx)); | |
| 1621 | if (const clang::AlignedAttr *AA = casted_self->getAttr<clang::AlignedAttr>()) { | |
| 1622 | return AA->getAlignment(*casted_ctx); | |
| 1623 | } | |
| 1624 | // Zero means no explicit alignment factor was specified | |
| 1625 | return 0; | |
| 1626 | } | |
| 1627 | ||
| 1618 | 1628 | unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionDecl *self, const ZigClangASTContext* ctx) { |
| 1619 | 1629 | auto casted_self = reinterpret_cast<const clang::FunctionDecl *>(self); |
| 1620 | 1630 | auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx)); |
src/zig_clang.h+1| ... | ... | @@ -865,6 +865,7 @@ ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(cons |
| 865 | 865 | ZIG_EXTERN_C const char* ZigClangVarDecl_getSectionAttribute(const struct ZigClangVarDecl *self, size_t *len); |
| 866 | 866 | ZIG_EXTERN_C unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangVarDecl *self, const ZigClangASTContext* ctx); |
| 867 | 867 | ZIG_EXTERN_C unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionDecl *self, const ZigClangASTContext* ctx); |
| 868 | ZIG_EXTERN_C unsigned ZigClangFieldDecl_getAlignedAttribute(const struct ZigClangFieldDecl *self, const ZigClangASTContext* ctx); | |
| 868 | 869 | |
| 869 | 870 | ZIG_EXTERN_C struct ZigClangQualType ZigClangParmVarDecl_getOriginalType(const struct ZigClangParmVarDecl *self); |
| 870 | 871 |
test/translate_c.zig+15-5| ... | ... | @@ -3,6 +3,16 @@ const std = @import("std"); |
| 3 | 3 | const CrossTarget = std.zig.CrossTarget; |
| 4 | 4 | |
| 5 | 5 | pub fn addCases(cases: *tests.TranslateCContext) void { |
| 6 | cases.add("struct with aligned fields", | |
| 7 | \\struct foo { | |
| 8 | \\ __attribute__((aligned(1))) short bar; | |
| 9 | \\}; | |
| 10 | , &[_][]const u8{ | |
| 11 | \\pub const struct_foo = extern struct { | |
| 12 | \\ bar: c_short align(1), | |
| 13 | \\}; | |
| 14 | }); | |
| 15 | ||
| 6 | 16 | cases.add("structs with VLAs are rejected", |
| 7 | 17 | \\struct foo { int x; int y[]; }; |
| 8 | 18 | \\struct bar { int x; int y[0]; }; |
| ... | ... | @@ -1429,7 +1439,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1429 | 1439 | cases.add("macro pointer cast", |
| 1430 | 1440 | \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) |
| 1431 | 1441 | , &[_][]const u8{ |
| 1432 | \\pub const NRF_GPIO = (if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE)); | |
| 1442 | \\pub const NRF_GPIO = (if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Int and @typeInfo([*c]NRF_GPIO_Type) == .Pointer) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE)); | |
| 1433 | 1443 | }); |
| 1434 | 1444 | |
| 1435 | 1445 | cases.add("basic macro function", |
| ... | ... | @@ -1601,7 +1611,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1601 | 1611 | cases.add("shadowing primitive types", |
| 1602 | 1612 | \\unsigned anyerror = 2; |
| 1603 | 1613 | , &[_][]const u8{ |
| 1604 | \\pub export var _anyerror: c_uint = @bitCast(c_uint, @as(c_int, 2)); | |
| 1614 | \\pub export var anyerror_1: c_uint = @bitCast(c_uint, @as(c_int, 2)); | |
| 1605 | 1615 | }); |
| 1606 | 1616 | |
| 1607 | 1617 | cases.add("floats", |
| ... | ... | @@ -2613,11 +2623,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2613 | 2623 | \\#define FOO(bar) baz((void *)(baz)) |
| 2614 | 2624 | \\#define BAR (void*) a |
| 2615 | 2625 | , &[_][]const u8{ |
| 2616 | \\pub inline fn FOO(bar: var) @TypeOf(baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz)))) { | |
| 2617 | \\ return baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz))); | |
| 2626 | \\pub inline fn FOO(bar: var) @TypeOf(baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int and @typeInfo(*c_void) == .Pointer) @intToPtr(*c_void, baz) else @as(*c_void, baz)))) { | |
| 2627 | \\ return baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int and @typeInfo(*c_void) == .Pointer) @intToPtr(*c_void, baz) else @as(*c_void, baz))); | |
| 2618 | 2628 | \\} |
| 2619 | 2629 | , |
| 2620 | \\pub const BAR = (if (@typeInfo(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeInfo(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a)); | |
| 2630 | \\pub const BAR = (if (@typeInfo(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeInfo(@TypeOf(a)) == .Int and @typeInfo(*c_void) == .Pointer) @intToPtr(*c_void, a) else @as(*c_void, a)); | |
| 2621 | 2631 | }); |
| 2622 | 2632 | |
| 2623 | 2633 | cases.add("macro conditional operator", |