| author | |
| committer | |
| log | 9390e8b84883331757d3ce15cfca89279aceb090 |
| tree | 3856b6a33a8343dd9048fa8edcf7c44aac7ba6f3 |
| parent | 8492c46aded997240dbda201374fc84a7b3cf16b |
* Preserve packed attribute in C translated struct
* Add tests for packed C struct6 files changed, 43 insertions(+), 2 deletions(-)
src-self-hosted/clang.zig+1| ... | ... | @@ -768,6 +768,7 @@ pub extern fn ZigClangVarDecl_getCanonicalDecl(self: ?*const struct_ZigClangVarD |
| 768 | 768 | pub extern fn ZigClangVarDecl_getSectionAttribute(self: *const ZigClangVarDecl, len: *usize) ?[*]const u8; |
| 769 | 769 | pub extern fn ZigClangFunctionDecl_getAlignedAttribute(self: *const ZigClangFunctionDecl, *const ZigClangASTContext) c_uint; |
| 770 | 770 | pub extern fn ZigClangVarDecl_getAlignedAttribute(self: *const ZigClangVarDecl, *const ZigClangASTContext) c_uint; |
| 771 | pub extern fn ZigClangRecordDecl_getPackedAttribute(self: ?*const struct_ZigClangRecordDecl) bool; | |
| 771 | 772 | pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl; |
| 772 | 773 | pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl; |
| 773 | 774 | pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation; |
src-self-hosted/translate_c.zig+5-2| ... | ... | @@ -733,13 +733,16 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 733 | 733 | break :blk opaque; |
| 734 | 734 | }; |
| 735 | 735 | |
| 736 | const extern_tok = try appendToken(c, .Keyword_extern, "extern"); | |
| 736 | const layout_tok = try if (ZigClangRecordDecl_getPackedAttribute(record_decl)) | |
| 737 | appendToken(c, .Keyword_packed, "packed") | |
| 738 | else | |
| 739 | appendToken(c, .Keyword_extern, "extern"); | |
| 737 | 740 | const container_tok = try appendToken(c, container_kind, container_kind_name); |
| 738 | 741 | const lbrace_token = try appendToken(c, .LBrace, "{"); |
| 739 | 742 | |
| 740 | 743 | const container_node = try c.a().create(ast.Node.ContainerDecl); |
| 741 | 744 | container_node.* = .{ |
| 742 | .layout_token = extern_tok, | |
| 745 | .layout_token = layout_tok, | |
| 743 | 746 | .kind_token = container_tok, |
| 744 | 747 | .init_arg_expr = .None, |
| 745 | 748 | .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(c.a()), |
src/zig_clang.cpp+8| ... | ... | @@ -1597,6 +1597,14 @@ const char* ZigClangVarDecl_getSectionAttribute(const struct ZigClangVarDecl *se |
| 1597 | 1597 | return nullptr; |
| 1598 | 1598 | } |
| 1599 | 1599 | |
| 1600 | bool ZigClangRecordDecl_getPackedAttribute(const ZigClangRecordDecl *zig_record_decl) { | |
| 1601 | const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl); | |
| 1602 | if (record_decl->getAttr<clang::PackedAttr>()) { | |
| 1603 | return true; | |
| 1604 | } | |
| 1605 | return false; | |
| 1606 | } | |
| 1607 | ||
| 1600 | 1608 | unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangVarDecl *self, const ZigClangASTContext* ctx) { |
| 1601 | 1609 | auto casted_self = reinterpret_cast<const clang::VarDecl *>(self); |
| 1602 | 1610 | auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx)); |
src/zig_clang.h+1| ... | ... | @@ -863,6 +863,7 @@ ZIG_EXTERN_C const char* ZigClangVarDecl_getSectionAttribute(const struct ZigCla |
| 863 | 863 | ZIG_EXTERN_C unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangVarDecl *self, const ZigClangASTContext* ctx); |
| 864 | 864 | ZIG_EXTERN_C unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionDecl *self, const ZigClangASTContext* ctx); |
| 865 | 865 | |
| 866 | ZIG_EXTERN_C bool ZigClangRecordDecl_getPackedAttribute(const struct ZigClangRecordDecl *); | |
| 866 | 867 | ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *); |
| 867 | 868 | ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *); |
| 868 | 869 |
test/run_translated_c.zig+13| ... | ... | @@ -83,4 +83,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 83 | 83 | \\ return 0; |
| 84 | 84 | \\} |
| 85 | 85 | , ""); |
| 86 | ||
| 87 | cases.add("struct initializer - packed", | |
| 88 | \\#define _NO_CRT_STDIO_INLINE 1 | |
| 89 | \\#include <stdint.h> | |
| 90 | \\#include <stdlib.h> | |
| 91 | \\struct s {uint8_t x,y; | |
| 92 | \\ uint32_t z;} __attribute__((packed)) s0 = {1, 2}; | |
| 93 | \\int main() { | |
| 94 | \\ /* sizeof nor offsetof currently supported */ | |
| 95 | \\ if (((intptr_t)&s0.z - (intptr_t)&s0.x) != 2) abort(); | |
| 96 | \\ return 0; | |
| 97 | \\} | |
| 98 | , ""); | |
| 86 | 99 | } |
test/translate_c.zig+15| ... | ... | @@ -121,6 +121,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 121 | 121 | \\} |
| 122 | 122 | }); |
| 123 | 123 | |
| 124 | cases.add("struct initializer - packed", | |
| 125 | \\struct {int x,y,z;} __attribute__((packed)) s0 = {1, 2}; | |
| 126 | , &[_][]const u8{ | |
| 127 | \\const struct_unnamed_1 = packed struct { | |
| 128 | \\ x: c_int, | |
| 129 | \\ y: c_int, | |
| 130 | \\ z: c_int, | |
| 131 | \\}; | |
| 132 | \\pub export var s0: struct_unnamed_1 = struct_unnamed_1{ | |
| 133 | \\ .x = @as(c_int, 1), | |
| 134 | \\ .y = @as(c_int, 2), | |
| 135 | \\ .z = 0, | |
| 136 | \\}; | |
| 137 | }); | |
| 138 | ||
| 124 | 139 | cases.add("align() attribute", |
| 125 | 140 | \\__attribute__ ((aligned(128))) |
| 126 | 141 | \\extern char my_array[16]; |