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(
498498 stmt: *const ZigClangStmt,
499499 result_used: ResultUsed,
500500 lrvalue: LRValue,
501) !TransResult {
501) TransError!TransResult {
502502 const sc = ZigClangStmt_getStmtClass(stmt);
503503 switch (sc) {
504504 .BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used),
......@@ -512,6 +512,7 @@ fn transStmt(
512512 .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),
513513 .ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue),
514514 .InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used),
515 .ImplicitValueInitExprClass => return transImplicitValueInitExpr(rp, scope, @ptrCast(*const ZigClangExpr, stmt), result_used),
515516 else => {
516517 return revertAndWarn(
517518 rp,
......@@ -856,6 +857,13 @@ fn transImplicitCastExpr(
856857 .LValueToRValue, .NoOp => {
857858 return transExpr(rp, scope, sub_expr, .used, .r_value);
858859 },
860 .NullToPointer => {
861 return TransResult{
862 .node = try transCreateNodeNullLiteral(rp.c),
863 .node_scope = scope,
864 .child_scope = scope,
865 };
866 },
859867 else => |kind| return revertAndWarn(
860868 rp,
861869 error.UnsupportedTranslation,
......@@ -1040,21 +1048,33 @@ fn transInitListExpr(
10401048 expr: *const ZigClangInitListExpr,
10411049 used: ResultUsed,
10421050) TransError!TransResult {
1043 // TODO use anon literals once they work properly
10441051 const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr));
10451052 const qual_type = ZigClangQualType_getTypePtr(qt);
10461053 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
10471065 const arr_type = ZigClangType_getAsArrayTypeUnsafe(qual_type);
1066 const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, qual_type);
10481067 const child_qt = ZigClangArrayType_getElementType(arr_type);
10491068 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));
10511071 const leftover_count = all_count - init_count;
10521072
10531073 var init_node: *ast.Node.SuffixOp = undefined;
10541074 var cat_tok: ast.TokenIndex = undefined;
10551075 if (init_count != 0) {
1056 var type_node = try transQualType(rp, qt, source_loc);
1057 init_node = try transCreateNodeArrayInitializer(rp.c, type_node);
1076 const dot_tok = try appendToken(rp.c, .Period, ".");
1077 init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok);
10581078 var i: c_uint = 0;
10591079 while (i < init_count) : (i += 1) {
10601080 const elem_expr = ZigClangInitListExpr_getInit(expr, i);
......@@ -1072,8 +1092,8 @@ fn transInitListExpr(
10721092 cat_tok = try appendToken(rp.c, .PlusPlus, "++");
10731093 }
10741094
1075 var filler_type_node = try transQualType(rp, qt, source_loc);
1076 var filler_init_node = try transCreateNodeArrayInitializer(rp.c, filler_type_node);
1095 const dot_tok = try appendToken(rp.c, .Period, ".");
1096 var filler_init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok);
10771097 const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
10781098 try filler_init_node.op.ArrayInitializer.push((try transExpr(rp, scope, filler_val_expr, .used, .r_value)).node);
10791099 filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
......@@ -1116,6 +1136,58 @@ fn transInitListExpr(
11161136 };
11171137}
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
11191191fn findBlockScope(inner: *Scope) *Scope.Block {
11201192 var scope = inner;
11211193 while (true) : (scope = scope.parent orelse unreachable) {
......@@ -1593,12 +1665,35 @@ fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
15931665 return &node.base;
15941666}
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 {
15971692 _ = try appendToken(c, .LBrace, "{");
15981693 const node = try c.a().create(ast.Node.SuffixOp);
15991694 node.* = ast.Node.SuffixOp{
16001695 .base = ast.Node{ .id = .SuffixOp },
1601 .lhs = .{ .node = type_node },
1696 .lhs = .{ .dot = dot_tok },
16021697 .op = .{
16031698 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
16041699 },
......@@ -1753,7 +1848,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
17531848 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
17541849
17551850 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
1756 // const typedef_name = rp.c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl))).?.value;
17571851 const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
17581852 return appendIdentifier(rp.c, typedef_name);
17591853 },
test/translate_c.zig+16
......@@ -252,6 +252,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
252252 \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
253253 });
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
255271 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
256272
257273 cases.add_both("typedef of function in struct field",