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
signaturebadge-question-mark 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...@@ -668,6 +668,31 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
668 return transCreateNodeIdentifier(c, builtin_name);668 return transCreateNodeIdentifier(c, builtin_name);
669}669}
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
671fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {696fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {
672 if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|697 if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|
673 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice698 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
...@@ -678,54 +703,36 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l...@@ -678,54 +703,36 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
678 // TODO https://github.com/ziglang/zig/issues/3756703 // TODO https://github.com/ziglang/zig/issues/3756
679 // TODO https://github.com/ziglang/zig/issues/1802704 // TODO https://github.com/ziglang/zig/issues/1802
680 const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;705 const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
681706 if (try checkForBuiltinTypedef(checked_name)) |builtin| {
682 if (mem.eql(u8, checked_name, "uint8_t"))707 return transTypeDefAsBuiltin(c, typedef_decl, builtin);
683 return transTypeDefAsBuiltin(c, typedef_decl, "u8")708 }
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");
706709
707 if (!top_level_visit) {710 if (!top_level_visit) {
708 return transCreateNodeIdentifier(c, checked_name);711 return transCreateNodeIdentifier(c, checked_name);
709 }712 }
710713
711 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);714 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);
712 const visib_tok = try appendToken(c, .Keyword_pub, "pub");715 const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
713 const const_tok = try appendToken(c, .Keyword_const, "const");716 try addTopLevelDecl(c, checked_name, &node.base);
714 const node = try transCreateNodeVarDecl(c, true, true, checked_name);717 return transCreateNodeIdentifier(c, checked_name);
715 node.eq_token = try appendToken(c, .Equal, "=");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
717 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);724 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
718 const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);725 const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);
719 node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {726 node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
720 error.UnsupportedType => {727 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", .{});
722 return null;729 return null;
723 },730 },
724 error.OutOfMemory => |e| return e,731 error.OutOfMemory => |e| return e,
725 };732 };
726 node.semicolon_token = try appendToken(c, .Semicolon, ";");733
727 try addTopLevelDecl(c, checked_name, &node.base);734 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
728 return transCreateNodeIdentifier(c, checked_name);735 return node;
729}736}
730737
731fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*ast.Node {738fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*ast.Node {
...@@ -1394,6 +1401,26 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)...@@ -1394,6 +1401,26 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
1394 node.semicolon_token = try appendToken(c, .Semicolon, ";");1401 node.semicolon_token = try appendToken(c, .Semicolon, ";");
1395 try block_scope.block_node.statements.push(&node.base);1402 try block_scope.block_node.statements.push(&node.base);
1396 },1403 },
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 },
1397 else => |kind| return revertAndWarn(1424 else => |kind| return revertAndWarn(
1398 rp,1425 rp,
1399 error.UnsupportedTranslation,1426 error.UnsupportedTranslation,
test/run_translated_c.zig+13
...@@ -243,4 +243,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {...@@ -243,4 +243,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
243 \\ return 0;243 \\ return 0;
244 \\}244 \\}
245 , "");245 , "");
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 , "");
246}259}