From c5198bd76f96d7dab64fdd8d81fc8028187b1403 Mon Sep 17 00:00:00 2001 From: Matthew Knight Date: Sat, 2 May 2020 20:22:43 -0700 Subject: [PATCH 1/4] added scoped typedef to translate-c --- src-self-hosted/translate_c.zig | 18 ++++++++++++++++++ test/run_translated_c.zig | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 1c689e9f76..a204469b83 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -1394,6 +1394,24 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) node.semicolon_token = try appendToken(c, .Semicolon, ";"); try block_scope.block_node.statements.push(&node.base); }, + .Typedef => { + const type_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]); + const name = try c.str(ZigClangNamedDecl_getName_bytes_begin( + @ptrCast(*const ZigClangNamedDecl, type_decl), + )); + + const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(type_decl); + const underlying_type = ZigClangQualType_getTypePtr(underlying_qual); + + const mangled_name = try block_scope.makeMangledName(c, name); + const node = try transCreateNodeVarDecl(c, false, true, mangled_name); + node.eq_token = try appendToken(c, .Equal, "="); + + const loc = ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)); + node.init_node = try transType(rp, underlying_type, loc); + node.semicolon_token = try appendToken(c, .Semicolon, ";"); + try block_scope.block_node.statements.push(&node.base); + }, else => |kind| return revertAndWarn( rp, error.UnsupportedTranslation, diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index ec6a11b9b4..a49fef76d1 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -243,4 +243,15 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { \\ return 0; \\} , ""); + + cases.add("scoped typedef", + \\int main(int argc, char **argv) { + \\ typedef int Foo; + \\ typedef Foo Bar; + \\ typedef void (*func)(int); + \\ Foo i; + \\ Bar j; + \\ return 0; + \\} + , ""); } From db4833d4d607a91686dc37ed68e453e9538dc668 Mon Sep 17 00:00:00 2001 From: Matthew Knight Date: Mon, 4 May 2020 23:45:31 -0700 Subject: [PATCH 2/4] moved duplicated code to common functions --- src-self-hosted/translate_c.zig | 66 ++++++++++++++++++--------------- test/run_translated_c.zig | 2 + 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index a204469b83..2a8817977b 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -668,17 +668,7 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe return transCreateNodeIdentifier(c, builtin_name); } -fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node { - if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv| - return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice - const rp = makeRestorePoint(c); - - const typedef_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, typedef_decl))); - - // TODO https://github.com/ziglang/zig/issues/3756 - // TODO https://github.com/ziglang/zig/issues/1802 - const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name; - +fn checkForBuiltinTypedef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, checked_name: []const u8) !?*ast.Node { if (mem.eql(u8, checked_name, "uint8_t")) return transTypeDefAsBuiltin(c, typedef_decl, "u8") else if (mem.eql(u8, checked_name, "int8_t")) @@ -704,28 +694,49 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l else if (mem.eql(u8, checked_name, "size_t")) return transTypeDefAsBuiltin(c, typedef_decl, "usize"); + return null; +} + +fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node { + if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv| + return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice + const rp = makeRestorePoint(c); + + const typedef_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, typedef_decl))); + + // TODO https://github.com/ziglang/zig/issues/3756 + // TODO https://github.com/ziglang/zig/issues/1802 + const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name; + if (try checkForBuiltinTypedef(c, typedef_decl, checked_name)) |node| { + return node; + } + if (!top_level_visit) { return transCreateNodeIdentifier(c, checked_name); } _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name); - const visib_tok = try appendToken(c, .Keyword_pub, "pub"); - const const_tok = try appendToken(c, .Keyword_const, "const"); - const node = try transCreateNodeVarDecl(c, true, true, checked_name); - node.eq_token = try appendToken(c, .Equal, "="); + const node = (try transZigTypedef(rp, typedef_decl, true, checked_name)) orelse return null; + try addTopLevelDecl(c, checked_name, &node.base); + return transCreateNodeIdentifier(c, checked_name); +} + +fn transZigTypedef(rp: RestorePoint, typedef_decl: *const ZigClangTypedefNameDecl, toplevel: bool, checked_name: []const u8) Error!?*ast.Node.VarDecl { + const node = try transCreateNodeVarDecl(rp.c, toplevel, true, checked_name); + node.eq_token = try appendToken(rp.c, .Equal, "="); const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl); node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) { error.UnsupportedType => { - try failDecl(c, typedef_loc, checked_name, "unable to resolve typedef child type", .{}); + try failDecl(rp.c, typedef_loc, checked_name, "unable to resolve typedef child type", .{}); return null; }, error.OutOfMemory => |e| return e, }; - node.semicolon_token = try appendToken(c, .Semicolon, ";"); - try addTopLevelDecl(c, checked_name, &node.base); - return transCreateNodeIdentifier(c, checked_name); + + node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); + return node; } fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*ast.Node { @@ -1395,21 +1406,18 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) try block_scope.block_node.statements.push(&node.base); }, .Typedef => { - const type_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]); + const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]); const name = try c.str(ZigClangNamedDecl_getName_bytes_begin( - @ptrCast(*const ZigClangNamedDecl, type_decl), + @ptrCast(*const ZigClangNamedDecl, typedef_decl), )); - const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(type_decl); - const underlying_type = ZigClangQualType_getTypePtr(underlying_qual); - const mangled_name = try block_scope.makeMangledName(c, name); - const node = try transCreateNodeVarDecl(c, false, true, mangled_name); - node.eq_token = try appendToken(c, .Equal, "="); + if (try checkForBuiltinTypedef(c, typedef_decl, mangled_name)) |ast_node| { + return ast_node; + } - const loc = ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)); - node.init_node = try transType(rp, underlying_type, loc); - node.semicolon_token = try appendToken(c, .Semicolon, ";"); + const node = (try transZigTypedef(rp, typedef_decl, false, mangled_name)) + orelse return error.UnsupportedTranslation; try block_scope.block_node.statements.push(&node.base); }, else => |kind| return revertAndWarn( diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index a49fef76d1..83569f1241 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -245,10 +245,12 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { , ""); cases.add("scoped typedef", + \\#include \\int main(int argc, char **argv) { \\ typedef int Foo; \\ typedef Foo Bar; \\ typedef void (*func)(int); + \\ typedef uint32_t Number; \\ Foo i; \\ Bar j; \\ return 0; From 52f0adb3052b284102f2a96c083c5dd28b7941d8 Mon Sep 17 00:00:00 2001 From: Matthew Knight Date: Tue, 5 May 2020 23:26:00 -0700 Subject: [PATCH 3/4] checkForBuiltinTypedef now returns a string --- src-self-hosted/translate_c.zig | 74 +++++++++++++++++---------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 2a8817977b..f7b080a749 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -668,31 +668,27 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe return transCreateNodeIdentifier(c, builtin_name); } -fn checkForBuiltinTypedef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, checked_name: []const u8) !?*ast.Node { - if (mem.eql(u8, checked_name, "uint8_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "u8") - else if (mem.eql(u8, checked_name, "int8_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "i8") - else if (mem.eql(u8, checked_name, "uint16_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "u16") - else if (mem.eql(u8, checked_name, "int16_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "i16") - else if (mem.eql(u8, checked_name, "uint32_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "u32") - else if (mem.eql(u8, checked_name, "int32_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "i32") - else if (mem.eql(u8, checked_name, "uint64_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "u64") - else if (mem.eql(u8, checked_name, "int64_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "i64") - else if (mem.eql(u8, checked_name, "intptr_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "isize") - else if (mem.eql(u8, checked_name, "uintptr_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "usize") - else if (mem.eql(u8, checked_name, "ssize_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "isize") - else if (mem.eql(u8, checked_name, "size_t")) - return transTypeDefAsBuiltin(c, typedef_decl, "usize"); +fn checkForBuiltinTypedef(checked_name: []const u8) !?[]const u8 { + const table = comptime [_][2][]const u8{ + .{ "uint8_t", "u8" }, + .{ "int8_t", "i8" }, + .{ "uint16_t", "u16" }, + .{ "int16_t", "i16" }, + .{ "uint32_t", "u32" }, + .{ "int32_t", "i32" }, + .{ "uint64_t", "u64" }, + .{ "int64_t", "i64" }, + .{ "intptr_t", "isize" }, + .{ "uintptr_t", "usize" }, + .{ "ssize_t", "isize" }, + .{ "size_t", "usize" }, + }; + + for (table) |entry| { + if (mem.eql(u8, checked_name, entry[0])) { + return entry[1]; + } + } return null; } @@ -707,8 +703,8 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l // TODO https://github.com/ziglang/zig/issues/3756 // TODO https://github.com/ziglang/zig/issues/1802 const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name; - if (try checkForBuiltinTypedef(c, typedef_decl, checked_name)) |node| { - return node; + if (try checkForBuiltinTypedef(checked_name)) |builtin| { + return transTypeDefAsBuiltin(c, typedef_decl, builtin); } if (!top_level_visit) { @@ -716,12 +712,12 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l } _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name); - const node = (try transZigTypedef(rp, typedef_decl, true, checked_name)) orelse return null; + const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null; try addTopLevelDecl(c, checked_name, &node.base); return transCreateNodeIdentifier(c, checked_name); } -fn transZigTypedef(rp: RestorePoint, typedef_decl: *const ZigClangTypedefNameDecl, toplevel: bool, checked_name: []const u8) Error!?*ast.Node.VarDecl { +fn transCreateNodeTypedef(rp: RestorePoint, typedef_decl: *const ZigClangTypedefNameDecl, toplevel: bool, checked_name: []const u8) Error!?*ast.Node.VarDecl { const node = try transCreateNodeVarDecl(rp.c, toplevel, true, checked_name); node.eq_token = try appendToken(rp.c, .Equal, "="); @@ -1411,14 +1407,20 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) @ptrCast(*const ZigClangNamedDecl, typedef_decl), )); - const mangled_name = try block_scope.makeMangledName(c, name); - if (try checkForBuiltinTypedef(c, typedef_decl, mangled_name)) |ast_node| { - return ast_node; - } + const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); + const underlying_type = ZigClangQualType_getTypePtr(underlying_qual); + const underlying_name = try c.str(ZigClangType_getTypeClassName(underlying_type)); - const node = (try transZigTypedef(rp, typedef_decl, false, mangled_name)) - orelse return error.UnsupportedTranslation; - try block_scope.block_node.statements.push(&node.base); + const mangled_name = try block_scope.makeMangledName(c, name); + if (try checkForBuiltinTypedef(underlying_name)) |builtin| { + try block_scope.variables.push(.{ + .alias = builtin, + .name = mangled_name, + }); + } else { + const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation; + try block_scope.block_node.statements.push(&node.base); + } }, else => |kind| return revertAndWarn( rp, From c0b269bf46d6257112f08a3c48904dd5654c97e8 Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 6 May 2020 11:48:46 +0300 Subject: [PATCH 4/4] translate-c: small patch to fix bultin type detection --- src-self-hosted/translate_c.zig | 5 ++--- test/run_translated_c.zig | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index f7b080a749..b515791f77 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -669,7 +669,7 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe } fn checkForBuiltinTypedef(checked_name: []const u8) !?[]const u8 { - const table = comptime [_][2][]const u8{ + const table = [_][2][]const u8{ .{ "uint8_t", "u8" }, .{ "int8_t", "i8" }, .{ "uint16_t", "u16" }, @@ -1409,10 +1409,9 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); const underlying_type = ZigClangQualType_getTypePtr(underlying_qual); - const underlying_name = try c.str(ZigClangType_getTypeClassName(underlying_type)); const mangled_name = try block_scope.makeMangledName(c, name); - if (try checkForBuiltinTypedef(underlying_name)) |builtin| { + if (try checkForBuiltinTypedef(name)) |builtin| { try block_scope.variables.push(.{ .alias = builtin, .name = mangled_name, diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 83569f1241..7dc64f068f 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -245,12 +245,12 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { , ""); cases.add("scoped typedef", - \\#include \\int main(int argc, char **argv) { \\ typedef int Foo; \\ typedef Foo Bar; \\ typedef void (*func)(int); - \\ typedef uint32_t Number; + \\ typedef int uint32_t; + \\ uint32_t a; \\ Foo i; \\ Bar j; \\ return 0;