Skip to content

Commit 6ff70d3

Browse files
LemonBoyandrewrk
authored andcommitted
Better InitListExpr translation
1 parent 5888d84 commit 6ff70d3

File tree

5 files changed

+67
-22
lines changed

5 files changed

+67
-22
lines changed

src-self-hosted/clang.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,8 @@ pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType
802802
pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;
803803
pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType;
804804
pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
805+
pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;
806+
pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;
805807
pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;
806808
pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
807809
pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;

src-self-hosted/translate_c.zig

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,30 +1851,18 @@ fn transInitListExprRecord(
18511851
return &init_node.base;
18521852
}
18531853

1854-
fn transInitListExpr(
1854+
fn transInitListExprArray(
18551855
rp: RestorePoint,
18561856
scope: *Scope,
1857+
loc: ZigClangSourceLocation,
18571858
expr: *const ZigClangInitListExpr,
1859+
ty: *const ZigClangType,
18581860
used: ResultUsed,
18591861
) TransError!*ast.Node {
1860-
const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr));
1861-
const qual_type = ZigClangQualType_getTypePtr(qt);
1862-
const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr));
1863-
switch (ZigClangType_getTypeClass(qual_type)) {
1864-
.ConstantArray => {},
1865-
.Record, .Elaborated => {
1866-
return transInitListExprRecord(rp, scope, source_loc, expr, qual_type, used);
1867-
},
1868-
else => {
1869-
const type_name = rp.c.str(ZigClangType_getTypeClassName(qual_type));
1870-
return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported initlist type: '{}'", .{type_name});
1871-
},
1872-
}
1873-
1874-
const arr_type = ZigClangType_getAsArrayTypeUnsafe(qual_type);
1862+
const arr_type = ZigClangType_getAsArrayTypeUnsafe(ty);
18751863
const child_qt = ZigClangArrayType_getElementType(arr_type);
18761864
const init_count = ZigClangInitListExpr_getNumInits(expr);
1877-
const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, qual_type);
1865+
const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, ty);
18781866
const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty);
18791867
const all_count = ZigClangAPInt_getLimitedValue(size_ap_int, math.maxInt(usize));
18801868
const leftover_count = all_count - init_count;
@@ -1931,6 +1919,40 @@ fn transInitListExpr(
19311919
return &cat_node.base;
19321920
}
19331921

1922+
fn transInitListExpr(
1923+
rp: RestorePoint,
1924+
scope: *Scope,
1925+
expr: *const ZigClangInitListExpr,
1926+
used: ResultUsed,
1927+
) TransError!*ast.Node {
1928+
const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr));
1929+
var qual_type = ZigClangQualType_getTypePtr(qt);
1930+
const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr));
1931+
1932+
if (ZigClangType_isRecordType(qual_type)) {
1933+
return transInitListExprRecord(
1934+
rp,
1935+
scope,
1936+
source_loc,
1937+
expr,
1938+
qual_type,
1939+
used,
1940+
);
1941+
} else if (ZigClangType_isArrayType(qual_type)) {
1942+
return transInitListExprArray(
1943+
rp,
1944+
scope,
1945+
source_loc,
1946+
expr,
1947+
qual_type,
1948+
used,
1949+
);
1950+
} else {
1951+
const type_name = rp.c.str(ZigClangType_getTypeClassName(qual_type));
1952+
return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported initlist type: '{}'", .{type_name});
1953+
}
1954+
}
1955+
19341956
fn transZeroInitExpr(
19351957
rp: RestorePoint,
19361958
scope: *Scope,

src/zig_clang.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,6 +1814,16 @@ bool ZigClangType_isVoidType(const ZigClangType *self) {
18141814
return casted->isVoidType();
18151815
}
18161816

1817+
bool ZigClangType_isArrayType(const ZigClangType *self) {
1818+
auto casted = reinterpret_cast<const clang::Type *>(self);
1819+
return casted->isArrayType();
1820+
}
1821+
1822+
bool ZigClangType_isRecordType(const ZigClangType *self) {
1823+
auto casted = reinterpret_cast<const clang::Type *>(self);
1824+
return casted->isRecordType();
1825+
}
1826+
18171827
const char *ZigClangType_getTypeClassName(const ZigClangType *self) {
18181828
auto casted = reinterpret_cast<const clang::Type *>(self);
18191829
return casted->getTypeClassName();

src/zig_clang.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,8 @@ ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType);
932932
ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self);
933933
ZIG_EXTERN_C struct ZigClangQualType ZigClangType_getPointeeType(const struct ZigClangType *self);
934934
ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
935+
ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);
936+
ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self);
935937
ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self);
936938
ZIG_EXTERN_C const struct ZigClangArrayType *ZigClangType_getAsArrayTypeUnsafe(const struct ZigClangType *self);
937939
ZIG_EXTERN_C const ZigClangRecordType *ZigClangType_getAsRecordType(const ZigClangType *self);

test/translate_c.zig

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,44 +31,53 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3131
});
3232

3333
cases.add("struct initializer - simple",
34+
\\typedef struct { int x; } foo;
3435
\\struct {double x,y,z;} s0 = {1.2, 1.3};
3536
\\struct {int sec,min,hour,day,mon,year;} s1 = {.day=31,12,2014,.sec=30,15,17};
3637
\\struct {int x,y;} s2 = {.y = 2, .x=1};
38+
\\foo s3 = { 123 };
3739
, &[_][]const u8{
3840
\\const struct_unnamed_1 = extern struct {
41+
\\ x: c_int,
42+
\\};
43+
\\pub const foo = struct_unnamed_1;
44+
\\const struct_unnamed_2 = extern struct {
3945
\\ x: f64,
4046
\\ y: f64,
4147
\\ z: f64,
4248
\\};
43-
\\pub export var s0: struct_unnamed_1 = struct_unnamed_1{
49+
\\pub export var s0: struct_unnamed_2 = struct_unnamed_2{
4450
\\ .x = 1.2,
4551
\\ .y = 1.3,
4652
\\ .z = 0,
4753
\\};
48-
\\const struct_unnamed_2 = extern struct {
54+
\\const struct_unnamed_3 = extern struct {
4955
\\ sec: c_int,
5056
\\ min: c_int,
5157
\\ hour: c_int,
5258
\\ day: c_int,
5359
\\ mon: c_int,
5460
\\ year: c_int,
5561
\\};
56-
\\pub export var s1: struct_unnamed_2 = struct_unnamed_2{
62+
\\pub export var s1: struct_unnamed_3 = struct_unnamed_3{
5763
\\ .sec = @as(c_int, 30),
5864
\\ .min = @as(c_int, 15),
5965
\\ .hour = @as(c_int, 17),
6066
\\ .day = @as(c_int, 31),
6167
\\ .mon = @as(c_int, 12),
6268
\\ .year = @as(c_int, 2014),
6369
\\};
64-
\\const struct_unnamed_3 = extern struct {
70+
\\const struct_unnamed_4 = extern struct {
6571
\\ x: c_int,
6672
\\ y: c_int,
6773
\\};
68-
\\pub export var s2: struct_unnamed_3 = struct_unnamed_3{
74+
\\pub export var s2: struct_unnamed_4 = struct_unnamed_4{
6975
\\ .x = @as(c_int, 1),
7076
\\ .y = @as(c_int, 2),
7177
\\};
78+
\\pub export var s3: foo = foo{
79+
\\ .x = @as(c_int, 123),
80+
\\};
7281
});
7382

7483
cases.add("simple ptrCast for casts between opaque types",

0 commit comments

Comments
 (0)