authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-14 10:41:00+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-14 10:49:25+02:00
loga4ac6d15c42a4a06eb5e2bfe73224384d3613bf6
tree6ab9d82c1d8b9fb4631c535c0143e7b4b2e03544
parente4ca1f441bf0c54e3fd447a2db6567a936175002
signature Commit is signed but in an unrecognized format.

translate-c-2 array initializer expr


2 files changed, 120 insertions(+), 10 deletions(-)

src-self-hosted/translate_c.zig+104-10
...@@ -498,7 +498,7 @@ fn transStmt(...@@ -498,7 +498,7 @@ fn transStmt(
498 stmt: *const ZigClangStmt,498 stmt: *const ZigClangStmt,
499 result_used: ResultUsed,499 result_used: ResultUsed,
500 lrvalue: LRValue,500 lrvalue: LRValue,
501) !TransResult {501) TransError!TransResult {
502 const sc = ZigClangStmt_getStmtClass(stmt);502 const sc = ZigClangStmt_getStmtClass(stmt);
503 switch (sc) {503 switch (sc) {
504 .BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used),504 .BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used),
...@@ -512,6 +512,7 @@ fn transStmt(...@@ -512,6 +512,7 @@ fn transStmt(
512 .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),512 .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),
513 .ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue),513 .ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue),
514 .InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used),514 .InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used),
515 .ImplicitValueInitExprClass => return transImplicitValueInitExpr(rp, scope, @ptrCast(*const ZigClangExpr, stmt), result_used),
515 else => {516 else => {
516 return revertAndWarn(517 return revertAndWarn(
517 rp,518 rp,
...@@ -856,6 +857,13 @@ fn transImplicitCastExpr(...@@ -856,6 +857,13 @@ fn transImplicitCastExpr(
856 .LValueToRValue, .NoOp => {857 .LValueToRValue, .NoOp => {
857 return transExpr(rp, scope, sub_expr, .used, .r_value);858 return transExpr(rp, scope, sub_expr, .used, .r_value);
858 },859 },
860 .NullToPointer => {
861 return TransResult{
862 .node = try transCreateNodeNullLiteral(rp.c),
863 .node_scope = scope,
864 .child_scope = scope,
865 };
866 },
859 else => |kind| return revertAndWarn(867 else => |kind| return revertAndWarn(
860 rp,868 rp,
861 error.UnsupportedTranslation,869 error.UnsupportedTranslation,
...@@ -1040,21 +1048,33 @@ fn transInitListExpr(...@@ -1040,21 +1048,33 @@ fn transInitListExpr(
1040 expr: *const ZigClangInitListExpr,1048 expr: *const ZigClangInitListExpr,
1041 used: ResultUsed,1049 used: ResultUsed,
1042) TransError!TransResult {1050) TransError!TransResult {
1043 // TODO use anon literals once they work properly
1044 const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr));1051 const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr));
1045 const qual_type = ZigClangQualType_getTypePtr(qt);1052 const qual_type = ZigClangQualType_getTypePtr(qt);
1046 const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr));1053 const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr));
1054 switch (ZigClangType_getTypeClass(qual_type)) {
1055 .ConstantArray => {},
1056 .Record, .Elaborated => {
1057 return revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO initListExpr for structs", .{});
1058 },
1059 else => {
1060 const type_name = rp.c.str(ZigClangType_getTypeClassName(qual_type));
1061 return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported initlist type: '{}'", .{type_name});
1062 },
1063 }
1064
1047 const arr_type = ZigClangType_getAsArrayTypeUnsafe(qual_type);1065 const arr_type = ZigClangType_getAsArrayTypeUnsafe(qual_type);
1066 const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, qual_type);
1048 const child_qt = ZigClangArrayType_getElementType(arr_type);1067 const child_qt = ZigClangArrayType_getElementType(arr_type);
1049 const init_count = ZigClangInitListExpr_getNumInits(expr);1068 const init_count = ZigClangInitListExpr_getNumInits(expr);
1050 const all_count = 200; //ZigClangArrayType_getSize(arr_type);1069 const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty);
1070 const all_count = ZigClangAPInt_getLimitedValue(size_ap_int, std.math.maxInt(usize));
1051 const leftover_count = all_count - init_count;1071 const leftover_count = all_count - init_count;
10521072
1053 var init_node: *ast.Node.SuffixOp = undefined;1073 var init_node: *ast.Node.SuffixOp = undefined;
1054 var cat_tok: ast.TokenIndex = undefined;1074 var cat_tok: ast.TokenIndex = undefined;
1055 if (init_count != 0) {1075 if (init_count != 0) {
1056 var type_node = try transQualType(rp, qt, source_loc);1076 const dot_tok = try appendToken(rp.c, .Period, ".");
1057 init_node = try transCreateNodeArrayInitializer(rp.c, type_node);1077 init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok);
1058 var i: c_uint = 0;1078 var i: c_uint = 0;
1059 while (i < init_count) : (i += 1) {1079 while (i < init_count) : (i += 1) {
1060 const elem_expr = ZigClangInitListExpr_getInit(expr, i);1080 const elem_expr = ZigClangInitListExpr_getInit(expr, i);
...@@ -1072,8 +1092,8 @@ fn transInitListExpr(...@@ -1072,8 +1092,8 @@ fn transInitListExpr(
1072 cat_tok = try appendToken(rp.c, .PlusPlus, "++");1092 cat_tok = try appendToken(rp.c, .PlusPlus, "++");
1073 }1093 }
10741094
1075 var filler_type_node = try transQualType(rp, qt, source_loc);1095 const dot_tok = try appendToken(rp.c, .Period, ".");
1076 var filler_init_node = try transCreateNodeArrayInitializer(rp.c, filler_type_node);1096 var filler_init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok);
1077 const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);1097 const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
1078 try filler_init_node.op.ArrayInitializer.push((try transExpr(rp, scope, filler_val_expr, .used, .r_value)).node);1098 try filler_init_node.op.ArrayInitializer.push((try transExpr(rp, scope, filler_val_expr, .used, .r_value)).node);
1079 filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");1099 filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
...@@ -1116,6 +1136,58 @@ fn transInitListExpr(...@@ -1116,6 +1136,58 @@ fn transInitListExpr(
1116 };1136 };
1117}1137}
11181138
1139fn transImplicitValueInitExpr(
1140 rp: RestorePoint,
1141 scope: *Scope,
1142 expr: *const ZigClangExpr,
1143 used: ResultUsed,
1144) TransError!TransResult {
1145 const source_loc = ZigClangExpr_getBeginLoc(expr);
1146 const qt = getExprQualType(rp.c, expr);
1147 const ty = ZigClangQualType_getTypePtr(qt);
1148 const node = switch (ZigClangType_getTypeClass(ty)) {
1149 .Builtin => blk: {
1150 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
1151 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
1152 .Bool => {
1153 break :blk try transCreateNodeBoolLiteral(rp.c, false);
1154 },
1155 .Char_U,
1156 .UChar,
1157 .Char_S,
1158 .Char8,
1159 .SChar,
1160 .UShort,
1161 .UInt,
1162 .ULong,
1163 .ULongLong,
1164 .Short,
1165 .Int,
1166 .Long,
1167 .LongLong,
1168 .UInt128,
1169 .Int128,
1170 .Float,
1171 .Double,
1172 .Float128,
1173 .Float16,
1174 .LongDouble,
1175 => {
1176 break :blk try transCreateNodeInt(rp.c, 0);
1177 },
1178 else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
1179 }
1180 },
1181 .Pointer => try transCreateNodeNullLiteral(rp.c),
1182 else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "type does not have an implicit init value", .{}),
1183 };
1184 return TransResult{
1185 .node = node,
1186 .child_scope = scope,
1187 .node_scope = scope,
1188 };
1189}
1190
1119fn findBlockScope(inner: *Scope) *Scope.Block {1191fn findBlockScope(inner: *Scope) *Scope.Block {
1120 var scope = inner;1192 var scope = inner;
1121 while (true) : (scope = scope.parent orelse unreachable) {1193 while (true) : (scope = scope.parent orelse unreachable) {
...@@ -1593,12 +1665,35 @@ fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {...@@ -1593,12 +1665,35 @@ fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
1593 return &node.base;1665 return &node.base;
1594}1666}
15951667
1596fn transCreateNodeArrayInitializer(c: *Context, type_node: *ast.Node) !*ast.Node.SuffixOp {1668fn transCreateNodeNullLiteral(c: *Context) !*ast.Node {
1669 const token = try appendToken(c, .Keyword_null, "null");
1670 const node = try c.a().create(ast.Node.NullLiteral);
1671 node.* = ast.Node.NullLiteral{
1672 .base = ast.Node{ .id = .NullLiteral },
1673 .token = token,
1674 };
1675 return &node.base;
1676}
1677
1678fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
1679 const token = if (value)
1680 try appendToken(c, .Keyword_true, "true")
1681 else
1682 try appendToken(c, .Keyword_false, "false");
1683 const node = try c.a().create(ast.Node.BoolLiteral);
1684 node.* = ast.Node.BoolLiteral{
1685 .base = ast.Node{ .id = .BoolLiteral },
1686 .token = token,
1687 };
1688 return &node.base;
1689}
1690
1691fn transCreateNodeArrayInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {
1597 _ = try appendToken(c, .LBrace, "{");1692 _ = try appendToken(c, .LBrace, "{");
1598 const node = try c.a().create(ast.Node.SuffixOp);1693 const node = try c.a().create(ast.Node.SuffixOp);
1599 node.* = ast.Node.SuffixOp{1694 node.* = ast.Node.SuffixOp{
1600 .base = ast.Node{ .id = .SuffixOp },1695 .base = ast.Node{ .id = .SuffixOp },
1601 .lhs = .{ .node = type_node },1696 .lhs = .{ .dot = dot_tok },
1602 .op = .{1697 .op = .{
1603 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),1698 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
1604 },1699 },
...@@ -1753,7 +1848,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour...@@ -1753,7 +1848,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
1753 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);1848 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
17541849
1755 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);1850 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
1756 // const typedef_name = rp.c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl))).?.value;
1757 const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));1851 const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
1758 return appendIdentifier(rp.c, typedef_name);1852 return appendIdentifier(rp.c, typedef_name);
1759 },1853 },
test/translate_c.zig+16
...@@ -252,6 +252,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -252,6 +252,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
252 \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;252 \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
253 });253 });
254254
255 cases.add_2("array initializer expr",
256 \\static void foo(void){
257 \\ char arr[10] ={1};
258 \\ char *arr1[10] ={0};
259 \\}
260 , &[_][]const u8{
261 \\pub fn foo() void {
262 \\ var arr: [10]u8 = .{
263 \\ @as(u8, 1),
264 \\ } ++ .{0} ** 9;
265 \\ var arr1: [10][*c]u8 = .{
266 \\ null,
267 \\ } ++ .{null} ** 9;
268 \\}
269 });
270
255 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////271 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
256272
257 cases.add_both("typedef of function in struct field",273 cases.add_both("typedef of function in struct field",