diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index b98fa785d1d1..f58e8c2352d4 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -802,6 +802,8 @@ pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass; pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType; pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool; +pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool; +pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool; pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8; pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType; pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 57e67d4dd5df..e9d5f326ba2c 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -1851,30 +1851,18 @@ fn transInitListExprRecord( return &init_node.base; } -fn transInitListExpr( +fn transInitListExprArray( rp: RestorePoint, scope: *Scope, + loc: ZigClangSourceLocation, expr: *const ZigClangInitListExpr, + ty: *const ZigClangType, used: ResultUsed, ) TransError!*ast.Node { - const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr)); - const qual_type = ZigClangQualType_getTypePtr(qt); - const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr)); - switch (ZigClangType_getTypeClass(qual_type)) { - .ConstantArray => {}, - .Record, .Elaborated => { - return transInitListExprRecord(rp, scope, source_loc, expr, qual_type, used); - }, - else => { - const type_name = rp.c.str(ZigClangType_getTypeClassName(qual_type)); - return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported initlist type: '{}'", .{type_name}); - }, - } - - const arr_type = ZigClangType_getAsArrayTypeUnsafe(qual_type); + const arr_type = ZigClangType_getAsArrayTypeUnsafe(ty); const child_qt = ZigClangArrayType_getElementType(arr_type); const init_count = ZigClangInitListExpr_getNumInits(expr); - const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, qual_type); + const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, ty); const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty); const all_count = ZigClangAPInt_getLimitedValue(size_ap_int, math.maxInt(usize)); const leftover_count = all_count - init_count; @@ -1931,6 +1919,40 @@ fn transInitListExpr( return &cat_node.base; } +fn transInitListExpr( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangInitListExpr, + used: ResultUsed, +) TransError!*ast.Node { + const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr)); + var qual_type = ZigClangQualType_getTypePtr(qt); + const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr)); + + if (ZigClangType_isRecordType(qual_type)) { + return transInitListExprRecord( + rp, + scope, + source_loc, + expr, + qual_type, + used, + ); + } else if (ZigClangType_isArrayType(qual_type)) { + return transInitListExprArray( + rp, + scope, + source_loc, + expr, + qual_type, + used, + ); + } else { + const type_name = rp.c.str(ZigClangType_getTypeClassName(qual_type)); + return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported initlist type: '{}'", .{type_name}); + } +} + fn transZeroInitExpr( rp: RestorePoint, scope: *Scope, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 6217e17800e8..0b75ea64e3b5 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1814,6 +1814,16 @@ bool ZigClangType_isVoidType(const ZigClangType *self) { return casted->isVoidType(); } +bool ZigClangType_isArrayType(const ZigClangType *self) { + auto casted = reinterpret_cast(self); + return casted->isArrayType(); +} + +bool ZigClangType_isRecordType(const ZigClangType *self) { + auto casted = reinterpret_cast(self); + return casted->isRecordType(); +} + const char *ZigClangType_getTypeClassName(const ZigClangType *self) { auto casted = reinterpret_cast(self); return casted->getTypeClassName(); diff --git a/src/zig_clang.h b/src/zig_clang.h index 0b248a8121c8..0edd8fb128b5 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -932,6 +932,8 @@ ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType); ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self); ZIG_EXTERN_C struct ZigClangQualType ZigClangType_getPointeeType(const struct ZigClangType *self); ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self); +ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self); +ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self); ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self); ZIG_EXTERN_C const struct ZigClangArrayType *ZigClangType_getAsArrayTypeUnsafe(const struct ZigClangType *self); ZIG_EXTERN_C const ZigClangRecordType *ZigClangType_getAsRecordType(const ZigClangType *self); diff --git a/test/translate_c.zig b/test/translate_c.zig index 42b72e7cb959..1c5ee80a4a8e 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -31,21 +31,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void { }); cases.add("struct initializer - simple", + \\typedef struct { int x; } foo; \\struct {double x,y,z;} s0 = {1.2, 1.3}; \\struct {int sec,min,hour,day,mon,year;} s1 = {.day=31,12,2014,.sec=30,15,17}; \\struct {int x,y;} s2 = {.y = 2, .x=1}; + \\foo s3 = { 123 }; , &[_][]const u8{ \\const struct_unnamed_1 = extern struct { + \\ x: c_int, + \\}; + \\pub const foo = struct_unnamed_1; + \\const struct_unnamed_2 = extern struct { \\ x: f64, \\ y: f64, \\ z: f64, \\}; - \\pub export var s0: struct_unnamed_1 = struct_unnamed_1{ + \\pub export var s0: struct_unnamed_2 = struct_unnamed_2{ \\ .x = 1.2, \\ .y = 1.3, \\ .z = 0, \\}; - \\const struct_unnamed_2 = extern struct { + \\const struct_unnamed_3 = extern struct { \\ sec: c_int, \\ min: c_int, \\ hour: c_int, @@ -53,7 +59,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ mon: c_int, \\ year: c_int, \\}; - \\pub export var s1: struct_unnamed_2 = struct_unnamed_2{ + \\pub export var s1: struct_unnamed_3 = struct_unnamed_3{ \\ .sec = @as(c_int, 30), \\ .min = @as(c_int, 15), \\ .hour = @as(c_int, 17), @@ -61,14 +67,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ .mon = @as(c_int, 12), \\ .year = @as(c_int, 2014), \\}; - \\const struct_unnamed_3 = extern struct { + \\const struct_unnamed_4 = extern struct { \\ x: c_int, \\ y: c_int, \\}; - \\pub export var s2: struct_unnamed_3 = struct_unnamed_3{ + \\pub export var s2: struct_unnamed_4 = struct_unnamed_4{ \\ .x = @as(c_int, 1), \\ .y = @as(c_int, 2), \\}; + \\pub export var s3: foo = foo{ + \\ .x = @as(c_int, 123), + \\}; }); cases.add("simple ptrCast for casts between opaque types",