| author | |
| committer | |
| log | bf678a12dfbdf0b3bb50804aa6b7ee081013049a |
| tree | c3ec70c8ffc0db33b747897bbec55bca8b84ff96 |
| parent | f83b02a581b2491e0a52f7c650ebd65ba8297263 |
| parent | 62413da9d3481d0fa5c0f53658af447de587f674 |
| signature | Commit is signed but in an unrecognized format. |
closes #40816 files changed, 107 insertions(+), 23 deletions(-)
src-self-hosted/clang.zig+2| ... | @@ -760,6 +760,7 @@ pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTU | ... | @@ -760,6 +760,7 @@ pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTU |
| 760 | pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl; | 760 | pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl; |
| 761 | pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl; | 761 | pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl; |
| 762 | pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl; | 762 | pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl; |
| 763 | pub extern fn ZigClangFieldDecl_getCanonicalDecl(field_decl: ?*const struct_ZigClangFieldDecl) ?*const struct_ZigClangFieldDecl; | ||
| 763 | pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl; | 764 | pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl; |
| 764 | pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl; | 765 | pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl; |
| 765 | pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl; | 766 | pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl; |
| ... | @@ -1055,6 +1056,7 @@ pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangSt | ... | @@ -1055,6 +1056,7 @@ pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangSt |
| 1055 | 1056 | ||
| 1056 | pub extern fn ZigClangParenExpr_getSubExpr(*const ZigClangParenExpr) *const ZigClangExpr; | 1057 | pub extern fn ZigClangParenExpr_getSubExpr(*const ZigClangParenExpr) *const ZigClangExpr; |
| 1057 | 1058 | ||
| 1059 | pub extern fn ZigClangFieldDecl_isAnonymousStructOrUnion(*const struct_ZigClangFieldDecl) bool; | ||
| 1058 | pub extern fn ZigClangFieldDecl_isBitField(*const struct_ZigClangFieldDecl) bool; | 1060 | pub extern fn ZigClangFieldDecl_isBitField(*const struct_ZigClangFieldDecl) bool; |
| 1059 | pub extern fn ZigClangFieldDecl_getType(*const struct_ZigClangFieldDecl) struct_ZigClangQualType; | 1061 | pub extern fn ZigClangFieldDecl_getType(*const struct_ZigClangFieldDecl) struct_ZigClangQualType; |
| 1060 | pub extern fn ZigClangFieldDecl_getLocation(*const struct_ZigClangFieldDecl) struct_ZigClangSourceLocation; | 1062 | pub extern fn ZigClangFieldDecl_getLocation(*const struct_ZigClangFieldDecl) struct_ZigClangSourceLocation; |
src-self-hosted/translate_c.zig+35-8| ... | @@ -759,8 +759,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -759,8 +759,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 759 | try emitWarning(c, field_loc, "{} demoted to opaque type - has bitfield", .{container_kind_name}); | 759 | try emitWarning(c, field_loc, "{} demoted to opaque type - has bitfield", .{container_kind_name}); |
| 760 | break :blk opaque; | 760 | break :blk opaque; |
| 761 | } | 761 | } |
| 762 | const raw_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))); | 762 | |
| 763 | if (raw_name.len < 1) continue; // fix weird windows bug? | 763 | var is_anon = false; |
| 764 | var raw_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))); | ||
| 765 | if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl) or raw_name.len == 0) { | ||
| 766 | raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()}); | ||
| 767 | is_anon = true; | ||
| 768 | } | ||
| 764 | const field_name = try appendIdentifier(c, raw_name); | 769 | const field_name = try appendIdentifier(c, raw_name); |
| 765 | _ = try appendToken(c, .Colon, ":"); | 770 | _ = try appendToken(c, .Colon, ":"); |
| 766 | const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) { | 771 | const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) { |
| ... | @@ -781,6 +786,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -781,6 +786,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 781 | .align_expr = null, | 786 | .align_expr = null, |
| 782 | }; | 787 | }; |
| 783 | 788 | ||
| 789 | if (is_anon) { | ||
| 790 | _ = try c.decl_table.put( | ||
| 791 | @ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl)), | ||
| 792 | raw_name, | ||
| 793 | ); | ||
| 794 | } | ||
| 795 | |||
| 784 | try container_node.fields_and_decls.push(&field_node.base); | 796 | try container_node.fields_and_decls.push(&field_node.base); |
| 785 | _ = try appendToken(c, .Comma, ","); | 797 | _ = try appendToken(c, .Comma, ","); |
| 786 | } | 798 | } |
| ... | @@ -1829,8 +1841,11 @@ fn transInitListExprRecord( | ... | @@ -1829,8 +1841,11 @@ fn transInitListExprRecord( |
| 1829 | // .field_name = expr | 1841 | // .field_name = expr |
| 1830 | const period_tok = try appendToken(rp.c, .Period, "."); | 1842 | const period_tok = try appendToken(rp.c, .Period, "."); |
| 1831 | 1843 | ||
| 1832 | const raw_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))); | 1844 | var raw_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))); |
| 1833 | if (raw_name.len < 1) continue; | 1845 | if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) { |
| 1846 | const name = rp.c.decl_table.get(@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl))).?; | ||
| 1847 | raw_name = try mem.dupe(rp.c.a(), u8, name.value); | ||
| 1848 | } | ||
| 1834 | const field_name_tok = try appendIdentifier(rp.c, raw_name); | 1849 | const field_name_tok = try appendIdentifier(rp.c, raw_name); |
| 1835 | 1850 | ||
| 1836 | _ = try appendToken(rp.c, .Equal, "="); | 1851 | _ = try appendToken(rp.c, .Equal, "="); |
| ... | @@ -2417,10 +2432,22 @@ fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberE | ... | @@ -2417,10 +2432,22 @@ fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberE |
| 2417 | container_node = try transCreateNodePtrDeref(rp.c, container_node); | 2432 | container_node = try transCreateNodePtrDeref(rp.c, container_node); |
| 2418 | } | 2433 | } |
| 2419 | 2434 | ||
| 2420 | const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, ZigClangMemberExpr_getMemberDecl(stmt)))); | 2435 | const member_decl = ZigClangMemberExpr_getMemberDecl(stmt); |
| 2421 | if (name.len == 0) { | 2436 | const name = blk: { |
| 2422 | return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)), "TODO access of anonymous field", .{}); | 2437 | const decl_kind = ZigClangDecl_getKind(@ptrCast(*const ZigClangDecl, member_decl)); |
| 2423 | } | 2438 | // If we're referring to a anonymous struct/enum find the bogus name |
| 2439 | // we've assigned to it during the RecordDecl translation | ||
| 2440 | if (decl_kind == .Field) { | ||
| 2441 | const field_decl = @ptrCast(*const struct_ZigClangFieldDecl, member_decl); | ||
| 2442 | if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) { | ||
| 2443 | const name = rp.c.decl_table.get(@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl))).?; | ||
| 2444 | break :blk try mem.dupe(rp.c.a(), u8, name.value); | ||
| 2445 | } | ||
| 2446 | } | ||
| 2447 | const decl = @ptrCast(*const ZigClangDecl, member_decl); | ||
| 2448 | break :blk try rp.c.str(ZigClangDecl_getName_bytes_begin(decl)); | ||
| 2449 | }; | ||
| 2450 | |||
| 2424 | const node = try transCreateNodeFieldAccess(rp.c, container_node, name); | 2451 | const node = try transCreateNodeFieldAccess(rp.c, container_node, name); |
| 2425 | return maybeSuppressResult(rp, scope, result_used, node); | 2452 | return maybeSuppressResult(rp, scope, result_used, node); |
| 2426 | } | 2453 | } |
src/zig_clang.cpp+9| ... | @@ -1562,6 +1562,11 @@ const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordD | ... | @@ -1562,6 +1562,11 @@ const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordD |
| 1562 | return reinterpret_cast<const ZigClangTagDecl *>(tag_decl); | 1562 | return reinterpret_cast<const ZigClangTagDecl *>(tag_decl); |
| 1563 | } | 1563 | } |
| 1564 | 1564 | ||
| 1565 | const ZigClangFieldDecl *ZigClangFieldDecl_getCanonicalDecl(const ZigClangFieldDecl *field_decl) { | ||
| 1566 | const clang::FieldDecl *canon_decl = reinterpret_cast<const clang::FieldDecl*>(field_decl)->getCanonicalDecl(); | ||
| 1567 | return reinterpret_cast<const ZigClangFieldDecl *>(canon_decl); | ||
| 1568 | } | ||
| 1569 | |||
| 1565 | const ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const ZigClangEnumDecl *enum_decl) { | 1570 | const ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const ZigClangEnumDecl *enum_decl) { |
| 1566 | const clang::TagDecl *tag_decl = reinterpret_cast<const clang::EnumDecl*>(enum_decl)->getCanonicalDecl(); | 1571 | const clang::TagDecl *tag_decl = reinterpret_cast<const clang::EnumDecl*>(enum_decl)->getCanonicalDecl(); |
| 1567 | return reinterpret_cast<const ZigClangTagDecl *>(tag_decl); | 1572 | return reinterpret_cast<const ZigClangTagDecl *>(tag_decl); |
| ... | @@ -2679,6 +2684,10 @@ bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *self) { | ... | @@ -2679,6 +2684,10 @@ bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *self) { |
| 2679 | return casted->isBitField(); | 2684 | return casted->isBitField(); |
| 2680 | } | 2685 | } |
| 2681 | 2686 | ||
| 2687 | bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *field_decl) { | ||
| 2688 | return reinterpret_cast<const clang::FieldDecl*>(field_decl)->isAnonymousStructOrUnion(); | ||
| 2689 | } | ||
| 2690 | |||
| 2682 | ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *self) { | 2691 | ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *self) { |
| 2683 | auto casted = reinterpret_cast<const clang::FieldDecl *>(self); | 2692 | auto casted = reinterpret_cast<const clang::FieldDecl *>(self); |
| 2684 | return bitcast(casted->getLocation()); | 2693 | return bitcast(casted->getLocation()); |
src/zig_clang.h+2| ... | @@ -855,6 +855,7 @@ ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struc | ... | @@ -855,6 +855,7 @@ ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struc |
| 855 | 855 | ||
| 856 | ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl); | 856 | ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl); |
| 857 | ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *); | 857 | ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *); |
| 858 | ZIG_EXTERN_C const struct ZigClangFieldDecl *ZigClangFieldDecl_getCanonicalDecl(const ZigClangFieldDecl *); | ||
| 858 | ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *); | 859 | ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *); |
| 859 | ZIG_EXTERN_C const struct ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self); | 860 | ZIG_EXTERN_C const struct ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self); |
| 860 | ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self); | 861 | ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self); |
| ... | @@ -1118,6 +1119,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSour | ... | @@ -1118,6 +1119,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSour |
| 1118 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEnd(const struct ZigClangMacroDefinitionRecord *); | 1119 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEnd(const struct ZigClangMacroDefinitionRecord *); |
| 1119 | 1120 | ||
| 1120 | ZIG_EXTERN_C bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *); | 1121 | ZIG_EXTERN_C bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *); |
| 1122 | ZIG_EXTERN_C bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *); | ||
| 1121 | ZIG_EXTERN_C struct ZigClangQualType ZigClangFieldDecl_getType(const struct ZigClangFieldDecl *); | 1123 | ZIG_EXTERN_C struct ZigClangQualType ZigClangFieldDecl_getType(const struct ZigClangFieldDecl *); |
| 1122 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *); | 1124 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *); |
| 1123 | 1125 |
test/run_translated_c.zig+14| ... | @@ -39,4 +39,18 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { | ... | @@ -39,4 +39,18 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 39 | \\ return 0; | 39 | \\ return 0; |
| 40 | \\} | 40 | \\} |
| 41 | , ""); | 41 | , ""); |
| 42 | |||
| 43 | cases.add("anonymous struct & unions", | ||
| 44 | \\#include <stdlib.h> | ||
| 45 | \\#include <stdint.h> | ||
| 46 | \\static struct { struct { uint16_t x, y; }; } x = { 1 }; | ||
| 47 | \\static struct { union { uint32_t x; uint8_t y; }; } y = { 0x55AA55AA }; | ||
| 48 | \\int main(int argc, char **argv) { | ||
| 49 | \\ if (x.x != 1) abort(); | ||
| 50 | \\ if (x.y != 0) abort(); | ||
| 51 | \\ if (y.x != 0x55AA55AA) abort(); | ||
| 52 | \\ if (y.y != 0xAA) abort(); | ||
| 53 | \\ return 0; | ||
| 54 | \\} | ||
| 55 | , ""); | ||
| 42 | } | 56 | } |
test/translate_c.zig+45-15| ... | @@ -8,6 +8,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -8,6 +8,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 8 | \\pub const VAL = 0xF00D; | 8 | \\pub const VAL = 0xF00D; |
| 9 | }); | 9 | }); |
| 10 | 10 | ||
| 11 | cases.add("anonymous struct & unions", | ||
| 12 | \\typedef struct { | ||
| 13 | \\ union { | ||
| 14 | \\ char x; | ||
| 15 | \\ struct { int y; }; | ||
| 16 | \\ }; | ||
| 17 | \\} outer; | ||
| 18 | \\void foo(outer *x) { x->y = x->x; } | ||
| 19 | , &[_][]const u8{ | ||
| 20 | \\const struct_unnamed_5 = extern struct { | ||
| 21 | \\ y: c_int, | ||
| 22 | \\}; | ||
| 23 | \\const union_unnamed_3 = extern union { | ||
| 24 | \\ x: u8, | ||
| 25 | \\ unnamed_4: struct_unnamed_5, | ||
| 26 | \\}; | ||
| 27 | \\const struct_unnamed_1 = extern struct { | ||
| 28 | \\ unnamed_2: union_unnamed_3, | ||
| 29 | \\}; | ||
| 30 | \\pub const outer = struct_unnamed_1; | ||
| 31 | \\pub export fn foo(arg_x: [*c]outer) void { | ||
| 32 | \\ var x = arg_x; | ||
| 33 | \\ x.*.unnamed_2.unnamed_4.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_2.x)); | ||
| 34 | \\} | ||
| 35 | }); | ||
| 36 | |||
| 11 | cases.add("union initializer", | 37 | cases.add("union initializer", |
| 12 | \\union { int x; char c[4]; } | 38 | \\union { int x; char c[4]; } |
| 13 | \\ ua = {1}, | 39 | \\ ua = {1}, |
| ... | @@ -1445,21 +1471,25 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1445,21 +1471,25 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1445 | \\} | 1471 | \\} |
| 1446 | }); | 1472 | }); |
| 1447 | 1473 | ||
| 1448 | cases.add("type referenced struct", | 1474 | if (builtin.os != .windows) { |
| 1449 | \\struct Foo { | 1475 | // When clang uses the <arch>-windows-none triple it behaves as MSVC and |
| 1450 | \\ struct Bar{ | 1476 | // interprets the inner `struct Bar` as an anonymous structure |
| 1451 | \\ int b; | 1477 | cases.add("type referenced struct", |
| 1452 | \\ }; | 1478 | \\struct Foo { |
| 1453 | \\ struct Bar c; | 1479 | \\ struct Bar{ |
| 1454 | \\}; | 1480 | \\ int b; |
| 1455 | , &[_][]const u8{ | 1481 | \\ }; |
| 1456 | \\pub const struct_Bar = extern struct { | 1482 | \\ struct Bar c; |
| 1457 | \\ b: c_int, | 1483 | \\}; |
| 1458 | \\}; | 1484 | , &[_][]const u8{ |
| 1459 | \\pub const struct_Foo = extern struct { | 1485 | \\pub const struct_Bar = extern struct { |
| 1460 | \\ c: struct_Bar, | 1486 | \\ b: c_int, |
| 1461 | \\}; | 1487 | \\}; |
| 1462 | }); | 1488 | \\pub const struct_Foo = extern struct { |
| 1489 | \\ c: struct_Bar, | ||
| 1490 | \\}; | ||
| 1491 | }); | ||
| 1492 | } | ||
| 1463 | 1493 | ||
| 1464 | cases.add("undefined array global", | 1494 | cases.add("undefined array global", |
| 1465 | \\int array[100] = {}; | 1495 | \\int array[100] = {}; |