Commit a4ac6d15c4
Changed files (2)
src-self-hosted
test
src-self-hosted/translate_c.zig
@@ -498,7 +498,7 @@ fn transStmt(
stmt: *const ZigClangStmt,
result_used: ResultUsed,
lrvalue: LRValue,
-) !TransResult {
+) TransError!TransResult {
const sc = ZigClangStmt_getStmtClass(stmt);
switch (sc) {
.BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used),
@@ -512,6 +512,7 @@ fn transStmt(
.StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),
.ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue),
.InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used),
+ .ImplicitValueInitExprClass => return transImplicitValueInitExpr(rp, scope, @ptrCast(*const ZigClangExpr, stmt), result_used),
else => {
return revertAndWarn(
rp,
@@ -856,6 +857,13 @@ fn transImplicitCastExpr(
.LValueToRValue, .NoOp => {
return transExpr(rp, scope, sub_expr, .used, .r_value);
},
+ .NullToPointer => {
+ return TransResult{
+ .node = try transCreateNodeNullLiteral(rp.c),
+ .node_scope = scope,
+ .child_scope = scope,
+ };
+ },
else => |kind| return revertAndWarn(
rp,
error.UnsupportedTranslation,
@@ -1040,21 +1048,33 @@ fn transInitListExpr(
expr: *const ZigClangInitListExpr,
used: ResultUsed,
) TransError!TransResult {
- // TODO use anon literals once they work properly
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 revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO initListExpr for structs", .{});
+ },
+ 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 const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, qual_type);
const child_qt = ZigClangArrayType_getElementType(arr_type);
const init_count = ZigClangInitListExpr_getNumInits(expr);
- const all_count = 200; //ZigClangArrayType_getSize(arr_type);
+ const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty);
+ const all_count = ZigClangAPInt_getLimitedValue(size_ap_int, std.math.maxInt(usize));
const leftover_count = all_count - init_count;
var init_node: *ast.Node.SuffixOp = undefined;
var cat_tok: ast.TokenIndex = undefined;
if (init_count != 0) {
- var type_node = try transQualType(rp, qt, source_loc);
- init_node = try transCreateNodeArrayInitializer(rp.c, type_node);
+ const dot_tok = try appendToken(rp.c, .Period, ".");
+ init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok);
var i: c_uint = 0;
while (i < init_count) : (i += 1) {
const elem_expr = ZigClangInitListExpr_getInit(expr, i);
@@ -1072,8 +1092,8 @@ fn transInitListExpr(
cat_tok = try appendToken(rp.c, .PlusPlus, "++");
}
- var filler_type_node = try transQualType(rp, qt, source_loc);
- var filler_init_node = try transCreateNodeArrayInitializer(rp.c, filler_type_node);
+ const dot_tok = try appendToken(rp.c, .Period, ".");
+ var filler_init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok);
const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
try filler_init_node.op.ArrayInitializer.push((try transExpr(rp, scope, filler_val_expr, .used, .r_value)).node);
filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
@@ -1116,6 +1136,58 @@ fn transInitListExpr(
};
}
+fn transImplicitValueInitExpr(
+ rp: RestorePoint,
+ scope: *Scope,
+ expr: *const ZigClangExpr,
+ used: ResultUsed,
+) TransError!TransResult {
+ const source_loc = ZigClangExpr_getBeginLoc(expr);
+ const qt = getExprQualType(rp.c, expr);
+ const ty = ZigClangQualType_getTypePtr(qt);
+ const node = switch (ZigClangType_getTypeClass(ty)) {
+ .Builtin => blk: {
+ const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
+ switch (ZigClangBuiltinType_getKind(builtin_ty)) {
+ .Bool => {
+ break :blk try transCreateNodeBoolLiteral(rp.c, false);
+ },
+ .Char_U,
+ .UChar,
+ .Char_S,
+ .Char8,
+ .SChar,
+ .UShort,
+ .UInt,
+ .ULong,
+ .ULongLong,
+ .Short,
+ .Int,
+ .Long,
+ .LongLong,
+ .UInt128,
+ .Int128,
+ .Float,
+ .Double,
+ .Float128,
+ .Float16,
+ .LongDouble,
+ => {
+ break :blk try transCreateNodeInt(rp.c, 0);
+ },
+ else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
+ }
+ },
+ .Pointer => try transCreateNodeNullLiteral(rp.c),
+ else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "type does not have an implicit init value", .{}),
+ };
+ return TransResult{
+ .node = node,
+ .child_scope = scope,
+ .node_scope = scope,
+ };
+}
+
fn findBlockScope(inner: *Scope) *Scope.Block {
var scope = inner;
while (true) : (scope = scope.parent orelse unreachable) {
@@ -1593,12 +1665,35 @@ fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
return &node.base;
}
-fn transCreateNodeArrayInitializer(c: *Context, type_node: *ast.Node) !*ast.Node.SuffixOp {
+fn transCreateNodeNullLiteral(c: *Context) !*ast.Node {
+ const token = try appendToken(c, .Keyword_null, "null");
+ const node = try c.a().create(ast.Node.NullLiteral);
+ node.* = ast.Node.NullLiteral{
+ .base = ast.Node{ .id = .NullLiteral },
+ .token = token,
+ };
+ return &node.base;
+}
+
+fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
+ const token = if (value)
+ try appendToken(c, .Keyword_true, "true")
+ else
+ try appendToken(c, .Keyword_false, "false");
+ const node = try c.a().create(ast.Node.BoolLiteral);
+ node.* = ast.Node.BoolLiteral{
+ .base = ast.Node{ .id = .BoolLiteral },
+ .token = token,
+ };
+ return &node.base;
+}
+
+fn transCreateNodeArrayInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {
_ = try appendToken(c, .LBrace, "{");
const node = try c.a().create(ast.Node.SuffixOp);
node.* = ast.Node.SuffixOp{
.base = ast.Node{ .id = .SuffixOp },
- .lhs = .{ .node = type_node },
+ .lhs = .{ .dot = dot_tok },
.op = .{
.ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
},
@@ -1753,7 +1848,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
- // const typedef_name = rp.c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl))).?.value;
const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
return appendIdentifier(rp.c, typedef_name);
},
test/translate_c.zig
@@ -252,6 +252,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
});
+ cases.add_2("array initializer expr",
+ \\static void foo(void){
+ \\ char arr[10] ={1};
+ \\ char *arr1[10] ={0};
+ \\}
+ , &[_][]const u8{
+ \\pub fn foo() void {
+ \\ var arr: [10]u8 = .{
+ \\ @as(u8, 1),
+ \\ } ++ .{0} ** 9;
+ \\ var arr1: [10][*c]u8 = .{
+ \\ null,
+ \\ } ++ .{null} ** 9;
+ \\}
+ });
+
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
cases.add_both("typedef of function in struct field",