| author | |
| committer | |
| log | 692a974c3edd05944d33cd579bcb355cdd7199fc |
| tree | 029600d5411dfd9c6b8b64b2c0c3df58ac3f340a |
| parent | 5aa993cd617e0ae3cabc9c626e45a748857e2f2a |
| signature |
5 files changed, 42 insertions(+), 3 deletions(-)
src-self-hosted/clang.zig+1| ... | @@ -812,6 +812,7 @@ pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) str | ... | @@ -812,6 +812,7 @@ pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) str |
| 812 | pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool; | 812 | pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool; |
| 813 | pub extern fn ZigClangType_isConstantArrayType(self: ?*const struct_ZigClangType) bool; | 813 | pub extern fn ZigClangType_isConstantArrayType(self: ?*const struct_ZigClangType) bool; |
| 814 | pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool; | 814 | pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool; |
| 815 | pub extern fn ZigClangType_isIncompleteOrZeroLengthArrayType(self: ?*const struct_ZigClangType, *const ZigClangASTContext) bool; | ||
| 815 | pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool; | 816 | pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool; |
| 816 | pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool; | 817 | pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool; |
| 817 | pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8; | 818 | pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8; |
src-self-hosted/translate_c.zig+11-3| ... | @@ -793,6 +793,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -793,6 +793,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 793 | while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) { | 793 | while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) { |
| 794 | const field_decl = ZigClangRecordDecl_field_iterator_deref(it); | 794 | const field_decl = ZigClangRecordDecl_field_iterator_deref(it); |
| 795 | const field_loc = ZigClangFieldDecl_getLocation(field_decl); | 795 | const field_loc = ZigClangFieldDecl_getLocation(field_decl); |
| 796 | const field_qt = ZigClangFieldDecl_getType(field_decl); | ||
| 796 | 797 | ||
| 797 | if (ZigClangFieldDecl_isBitField(field_decl)) { | 798 | if (ZigClangFieldDecl_isBitField(field_decl)) { |
| 798 | const opaque = try transCreateNodeOpaqueType(c); | 799 | const opaque = try transCreateNodeOpaqueType(c); |
| ... | @@ -801,6 +802,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -801,6 +802,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 801 | break :blk opaque; | 802 | break :blk opaque; |
| 802 | } | 803 | } |
| 803 | 804 | ||
| 805 | if (ZigClangType_isIncompleteOrZeroLengthArrayType(qualTypeCanon(field_qt), c.clang_context)) { | ||
| 806 | const opaque = try transCreateNodeOpaqueType(c); | ||
| 807 | semicolon = try appendToken(c, .Semicolon, ";"); | ||
| 808 | try emitWarning(c, field_loc, "{} demoted to opaque type - has variable length array", .{container_kind_name}); | ||
| 809 | break :blk opaque; | ||
| 810 | } | ||
| 811 | |||
| 804 | var is_anon = false; | 812 | var is_anon = false; |
| 805 | var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl))); | 813 | var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl))); |
| 806 | if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) { | 814 | if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) { |
| ... | @@ -809,7 +817,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -809,7 +817,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 809 | } | 817 | } |
| 810 | const field_name = try appendIdentifier(c, raw_name); | 818 | const field_name = try appendIdentifier(c, raw_name); |
| 811 | _ = try appendToken(c, .Colon, ":"); | 819 | _ = try appendToken(c, .Colon, ":"); |
| 812 | const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) { | 820 | const field_type = transQualType(rp, field_qt, field_loc) catch |err| switch (err) { |
| 813 | error.UnsupportedType => { | 821 | error.UnsupportedType => { |
| 814 | const opaque = try transCreateNodeOpaqueType(c); | 822 | const opaque = try transCreateNodeOpaqueType(c); |
| 815 | semicolon = try appendToken(c, .Semicolon, ";"); | 823 | semicolon = try appendToken(c, .Semicolon, ";"); |
| ... | @@ -5600,7 +5608,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5600,7 +5608,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5600 | }, | 5608 | }, |
| 5601 | .Ampersand => { | 5609 | .Ampersand => { |
| 5602 | op_token = try appendToken(c, .Ampersand, "&"); | 5610 | op_token = try appendToken(c, .Ampersand, "&"); |
| 5603 | op_id= .BitAnd; | 5611 | op_id = .BitAnd; |
| 5604 | }, | 5612 | }, |
| 5605 | .Plus => { | 5613 | .Plus => { |
| 5606 | op_token = try appendToken(c, .Plus, "+"); | 5614 | op_token = try appendToken(c, .Plus, "+"); |
| ... | @@ -5608,7 +5616,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5608,7 +5616,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5608 | }, | 5616 | }, |
| 5609 | .Minus => { | 5617 | .Minus => { |
| 5610 | op_token = try appendToken(c, .Minus, "-"); | 5618 | op_token = try appendToken(c, .Minus, "-"); |
| 5611 | op_id= .Sub; | 5619 | op_id = .Sub; |
| 5612 | }, | 5620 | }, |
| 5613 | .AmpersandAmpersand => { | 5621 | .AmpersandAmpersand => { |
| 5614 | op_token = try appendToken(c, .Keyword_and, "and"); | 5622 | op_token = try appendToken(c, .Keyword_and, "and"); |
src/zig_clang.cpp+20| ... | @@ -1881,6 +1881,26 @@ bool ZigClangType_isRecordType(const ZigClangType *self) { | ... | @@ -1881,6 +1881,26 @@ bool ZigClangType_isRecordType(const ZigClangType *self) { |
| 1881 | return casted->isRecordType(); | 1881 | return casted->isRecordType(); |
| 1882 | } | 1882 | } |
| 1883 | 1883 | ||
| 1884 | bool ZigClangType_isIncompleteOrZeroLengthArrayType(const ZigClangQualType *self, | ||
| 1885 | const struct ZigClangASTContext *ctx) | ||
| 1886 | { | ||
| 1887 | auto casted_ctx = reinterpret_cast<const clang::ASTContext *>(ctx); | ||
| 1888 | auto casted = reinterpret_cast<const clang::QualType *>(self); | ||
| 1889 | auto casted_type = reinterpret_cast<const clang::Type *>(self); | ||
| 1890 | if (casted_type->isIncompleteArrayType()) | ||
| 1891 | return true; | ||
| 1892 | |||
| 1893 | clang::QualType elem_type = *casted; | ||
| 1894 | while (const clang::ConstantArrayType *ArrayT = casted_ctx->getAsConstantArrayType(elem_type)) { | ||
| 1895 | if (ArrayT->getSize() == 0) | ||
| 1896 | return true; | ||
| 1897 | |||
| 1898 | elem_type = ArrayT->getElementType(); | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | return false; | ||
| 1902 | } | ||
| 1903 | |||
| 1884 | bool ZigClangType_isConstantArrayType(const ZigClangType *self) { | 1904 | bool ZigClangType_isConstantArrayType(const ZigClangType *self) { |
| 1885 | auto casted = reinterpret_cast<const clang::Type *>(self); | 1905 | auto casted = reinterpret_cast<const clang::Type *>(self); |
| 1886 | return casted->isConstantArrayType(); | 1906 | return casted->isConstantArrayType(); |
src/zig_clang.h+1| ... | @@ -947,6 +947,7 @@ ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self); | ... | @@ -947,6 +947,7 @@ ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self); |
| 947 | ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self); | 947 | ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self); |
| 948 | ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self); | 948 | ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self); |
| 949 | ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self); | 949 | ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self); |
| 950 | ZIG_EXTERN_C bool ZigClangType_isIncompleteOrZeroLengthArrayType(const ZigClangQualType *self, const struct ZigClangASTContext *ctx); | ||
| 950 | ZIG_EXTERN_C bool ZigClangType_isConstantArrayType(const ZigClangType *self); | 951 | ZIG_EXTERN_C bool ZigClangType_isConstantArrayType(const ZigClangType *self); |
| 951 | ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self); | 952 | ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self); |
| 952 | ZIG_EXTERN_C const struct ZigClangArrayType *ZigClangType_getAsArrayTypeUnsafe(const struct ZigClangType *self); | 953 | ZIG_EXTERN_C const struct ZigClangArrayType *ZigClangType_getAsArrayTypeUnsafe(const struct ZigClangType *self); |
test/translate_c.zig+9| ... | @@ -3,6 +3,15 @@ const std = @import("std"); | ... | @@ -3,6 +3,15 @@ const std = @import("std"); |
| 3 | const CrossTarget = std.zig.CrossTarget; | 3 | const CrossTarget = std.zig.CrossTarget; |
| 4 | 4 | ||
| 5 | pub fn addCases(cases: *tests.TranslateCContext) void { | 5 | pub fn addCases(cases: *tests.TranslateCContext) void { |
| 6 | cases.add("structs with VLAs are rejected", | ||
| 7 | \\struct foo { int x; int y[]; }; | ||
| 8 | \\struct bar { int x; int y[0]; }; | ||
| 9 | , &[_][]const u8{ | ||
| 10 | \\pub const struct_foo = @OpaqueType(); | ||
| 11 | , | ||
| 12 | \\pub const struct_bar = @OpaqueType(); | ||
| 13 | }); | ||
| 14 | |||
| 6 | cases.add("nested loops without blocks", | 15 | cases.add("nested loops without blocks", |
| 7 | \\void foo() { | 16 | \\void foo() { |
| 8 | \\ while (0) while (0) {} | 17 | \\ while (0) while (0) {} |