authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-06 12:28:30+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-05-06 12:28:30+03:00
log06e6d39c6c03989c117178033ef1188ded58a1d6
tree522644fb411f252a477e752e4682c4ecc0b8e1a3
parenteb4fa63d3d7f7bb04ce20f0545d5d4f14aa05c89
parentc0b269bf46d6257112f08a3c48904dd5654c97e8
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #5257 from matt1795/scoped-typedef

Add scoped typedef to translate-c

2 files changed, 73 insertions(+), 33 deletions(-)

src-self-hosted/translate_c.zig+60-33
......@@ -668,6 +668,31 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
668668 return transCreateNodeIdentifier(c, builtin_name);
669669}
670670
671fn checkForBuiltinTypedef(checked_name: []const u8) !?[]const u8 {
672 const table = [_][2][]const u8{
673 .{ "uint8_t", "u8" },
674 .{ "int8_t", "i8" },
675 .{ "uint16_t", "u16" },
676 .{ "int16_t", "i16" },
677 .{ "uint32_t", "u32" },
678 .{ "int32_t", "i32" },
679 .{ "uint64_t", "u64" },
680 .{ "int64_t", "i64" },
681 .{ "intptr_t", "isize" },
682 .{ "uintptr_t", "usize" },
683 .{ "ssize_t", "isize" },
684 .{ "size_t", "usize" },
685 };
686
687 for (table) |entry| {
688 if (mem.eql(u8, checked_name, entry[0])) {
689 return entry[1];
690 }
691 }
692
693 return null;
694}
695
671696fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {
672697 if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|
673698 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
......@@ -678,54 +703,36 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
678703 // TODO https://github.com/ziglang/zig/issues/3756
679704 // TODO https://github.com/ziglang/zig/issues/1802
680705 const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
681
682 if (mem.eql(u8, checked_name, "uint8_t"))
683 return transTypeDefAsBuiltin(c, typedef_decl, "u8")
684 else if (mem.eql(u8, checked_name, "int8_t"))
685 return transTypeDefAsBuiltin(c, typedef_decl, "i8")
686 else if (mem.eql(u8, checked_name, "uint16_t"))
687 return transTypeDefAsBuiltin(c, typedef_decl, "u16")
688 else if (mem.eql(u8, checked_name, "int16_t"))
689 return transTypeDefAsBuiltin(c, typedef_decl, "i16")
690 else if (mem.eql(u8, checked_name, "uint32_t"))
691 return transTypeDefAsBuiltin(c, typedef_decl, "u32")
692 else if (mem.eql(u8, checked_name, "int32_t"))
693 return transTypeDefAsBuiltin(c, typedef_decl, "i32")
694 else if (mem.eql(u8, checked_name, "uint64_t"))
695 return transTypeDefAsBuiltin(c, typedef_decl, "u64")
696 else if (mem.eql(u8, checked_name, "int64_t"))
697 return transTypeDefAsBuiltin(c, typedef_decl, "i64")
698 else if (mem.eql(u8, checked_name, "intptr_t"))
699 return transTypeDefAsBuiltin(c, typedef_decl, "isize")
700 else if (mem.eql(u8, checked_name, "uintptr_t"))
701 return transTypeDefAsBuiltin(c, typedef_decl, "usize")
702 else if (mem.eql(u8, checked_name, "ssize_t"))
703 return transTypeDefAsBuiltin(c, typedef_decl, "isize")
704 else if (mem.eql(u8, checked_name, "size_t"))
705 return transTypeDefAsBuiltin(c, typedef_decl, "usize");
706 if (try checkForBuiltinTypedef(checked_name)) |builtin| {
707 return transTypeDefAsBuiltin(c, typedef_decl, builtin);
708 }
706709
707710 if (!top_level_visit) {
708711 return transCreateNodeIdentifier(c, checked_name);
709712 }
710713
711714 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);
712 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
713 const const_tok = try appendToken(c, .Keyword_const, "const");
714 const node = try transCreateNodeVarDecl(c, true, true, checked_name);
715 node.eq_token = try appendToken(c, .Equal, "=");
715 const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
716 try addTopLevelDecl(c, checked_name, &node.base);
717 return transCreateNodeIdentifier(c, checked_name);
718}
719
720fn transCreateNodeTypedef(rp: RestorePoint, typedef_decl: *const ZigClangTypedefNameDecl, toplevel: bool, checked_name: []const u8) Error!?*ast.Node.VarDecl {
721 const node = try transCreateNodeVarDecl(rp.c, toplevel, true, checked_name);
722 node.eq_token = try appendToken(rp.c, .Equal, "=");
716723
717724 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
718725 const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);
719726 node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
720727 error.UnsupportedType => {
721 try failDecl(c, typedef_loc, checked_name, "unable to resolve typedef child type", .{});
728 try failDecl(rp.c, typedef_loc, checked_name, "unable to resolve typedef child type", .{});
722729 return null;
723730 },
724731 error.OutOfMemory => |e| return e,
725732 };
726 node.semicolon_token = try appendToken(c, .Semicolon, ";");
727 try addTopLevelDecl(c, checked_name, &node.base);
728 return transCreateNodeIdentifier(c, checked_name);
733
734 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
735 return node;
729736}
730737
731738fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*ast.Node {
......@@ -1394,6 +1401,26 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
13941401 node.semicolon_token = try appendToken(c, .Semicolon, ";");
13951402 try block_scope.block_node.statements.push(&node.base);
13961403 },
1404 .Typedef => {
1405 const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);
1406 const name = try c.str(ZigClangNamedDecl_getName_bytes_begin(
1407 @ptrCast(*const ZigClangNamedDecl, typedef_decl),
1408 ));
1409
1410 const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
1411 const underlying_type = ZigClangQualType_getTypePtr(underlying_qual);
1412
1413 const mangled_name = try block_scope.makeMangledName(c, name);
1414 if (try checkForBuiltinTypedef(name)) |builtin| {
1415 try block_scope.variables.push(.{
1416 .alias = builtin,
1417 .name = mangled_name,
1418 });
1419 } else {
1420 const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation;
1421 try block_scope.block_node.statements.push(&node.base);
1422 }
1423 },
13971424 else => |kind| return revertAndWarn(
13981425 rp,
13991426 error.UnsupportedTranslation,
test/run_translated_c.zig+13
......@@ -243,4 +243,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
243243 \\ return 0;
244244 \\}
245245 , "");
246
247 cases.add("scoped typedef",
248 \\int main(int argc, char **argv) {
249 \\ typedef int Foo;
250 \\ typedef Foo Bar;
251 \\ typedef void (*func)(int);
252 \\ typedef int uint32_t;
253 \\ uint32_t a;
254 \\ Foo i;
255 \\ Bar j;
256 \\ return 0;
257 \\}
258 , "");
246259}