authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-17 10:20:02+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-17 10:20:02+02:00
log9cda93a24e3f4eaae63f3a7a8da99e91f47222fa
tree0927ac1c2ab28d74dde21740ff9267165e7650e9
parentab6fe57462374d59b20ac46eeb4eefbf2f6938a0
signature Commit is signed but in an unrecognized format.

translate-c-2 don't shadow primitive types


2 files changed, 66 insertions(+), 27 deletions(-)

src-self-hosted/translate_c.zig+54-21
...@@ -69,9 +69,7 @@ const Scope = struct {...@@ -69,9 +69,7 @@ const Scope = struct {
69 label: ?[]const u8,69 label: ?[]const u8,
7070
71 /// Don't forget to set rbrace token and block_node later71 /// Don't forget to set rbrace token and block_node later
72 fn init(c: *Context, parent: *Scope, want_label: bool) !*Block {72 fn init(c: *Context, parent: *Scope, label: ?[]const u8) !*Block {
73 // TODO removing `?[]const u8` here causes LLVM error
74 const label: ?[]const u8 = if (want_label) try std.fmt.allocPrint(c.a(), "blk_{}", .{c.getMangle()}) else null;
75 const block = try c.a().create(Block);73 const block = try c.a().create(Block);
76 block.* = .{74 block.* = .{
77 .base = .{75 .base = .{
...@@ -171,7 +169,7 @@ const Scope = struct {...@@ -171,7 +169,7 @@ const Scope = struct {
171 .Condition => {169 .Condition => {
172 const cond = @fieldParentPtr(Condition, "base", scope);170 const cond = @fieldParentPtr(Condition, "base", scope);
173 // comma operator used171 // comma operator used
174 return try Block.init(c, scope, true);172 return try Block.init(c, scope, "blk");
175 },173 },
176 else => scope = scope.parent.?,174 else => scope = scope.parent.?,
177 }175 }
...@@ -179,7 +177,7 @@ const Scope = struct {...@@ -179,7 +177,7 @@ const Scope = struct {
179 }177 }
180178
181 fn createAlias(scope: *Scope, c: *Context, name: []const u8) !?[]const u8 {179 fn createAlias(scope: *Scope, c: *Context, name: []const u8) !?[]const u8 {
182 if (scope.contains(name)) {180 if (isZigPrimitiveType(name) or scope.contains(name)) {
183 return try std.fmt.allocPrint(c.a(), "{}_{}", .{ name, c.getMangle() });181 return try std.fmt.allocPrint(c.a(), "{}_{}", .{ name, c.getMangle() });
184 }182 }
185 return null;183 return null;
...@@ -452,7 +450,11 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {...@@ -452,7 +450,11 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
452450
453 const scope = &c.global_scope.base;451 const scope = &c.global_scope.base;
454 const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl)));452 const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl)));
455 _ = try c.decl_table.put(@ptrToInt(var_decl), var_name);453
454 // TODO https://github.com/ziglang/zig/issues/3756
455 // TODO https://github.com/ziglang/zig/issues/1802
456 const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.a(), "_{}", .{var_name}) else var_name;
457 _ = try c.decl_table.put(@ptrToInt(var_decl), checked_name);
456 const var_decl_loc = ZigClangVarDecl_getLocation(var_decl);458 const var_decl_loc = ZigClangVarDecl_getLocation(var_decl);
457459
458 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);460 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
...@@ -471,12 +473,12 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {...@@ -471,12 +473,12 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
471 else473 else
472 try appendToken(c, .Keyword_var, "var");474 try appendToken(c, .Keyword_var, "var");
473475
474 const name_tok = try appendIdentifier(c, var_name);476 const name_tok = try appendIdentifier(c, checked_name);
475477
476 _ = try appendToken(c, .Colon, ":");478 _ = try appendToken(c, .Colon, ":");
477 const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) {479 const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) {
478 error.UnsupportedType => {480 error.UnsupportedType => {
479 return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{});481 return failDecl(c, var_decl_loc, checked_name, "unable to resolve variable type", .{});
480 },482 },
481 error.OutOfMemory => |e| return e,483 error.OutOfMemory => |e| return e,
482 };484 };
...@@ -491,14 +493,14 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {...@@ -491,14 +493,14 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
491 error.UnsupportedTranslation,493 error.UnsupportedTranslation,
492 error.UnsupportedType,494 error.UnsupportedType,
493 => {495 => {
494 return failDecl(c, var_decl_loc, var_name, "unable to translate initializer", .{});496 return failDecl(c, var_decl_loc, checked_name, "unable to translate initializer", .{});
495 },497 },
496 error.OutOfMemory => |e| return e,498 error.OutOfMemory => |e| return e,
497 }499 }
498 else500 else
499 try transCreateNodeUndefinedLiteral(c);501 try transCreateNodeUndefinedLiteral(c);
500 } else if (storage_class != .Extern) {502 } else if (storage_class != .Extern) {
501 return failDecl(c, var_decl_loc, var_name, "non-extern variable has no initializer", .{});503 return failDecl(c, var_decl_loc, checked_name, "non-extern variable has no initializer", .{});
502 }504 }
503505
504 const node = try c.a().create(ast.Node.VarDecl);506 const node = try c.a().create(ast.Node.VarDecl);
...@@ -518,7 +520,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {...@@ -518,7 +520,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
518 .init_node = init_node,520 .init_node = init_node,
519 .semicolon_token = try appendToken(c, .Semicolon, ";"),521 .semicolon_token = try appendToken(c, .Semicolon, ";"),
520 };522 };
521 return addTopLevelDecl(c, var_name, &node.base);523 return addTopLevelDecl(c, checked_name, &node.base);
522}524}
523525
524fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!void {526fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!void {
...@@ -796,7 +798,7 @@ fn transCompoundStmtInline(...@@ -796,7 +798,7 @@ fn transCompoundStmtInline(
796}798}
797799
798fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {800fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {
799 const block_scope = try Scope.Block.init(rp.c, scope, false);801 const block_scope = try Scope.Block.init(rp.c, scope, null);
800 block_scope.block_node = try transCreateNodeBlock(rp.c, null);802 block_scope.block_node = try transCreateNodeBlock(rp.c, null);
801 try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);803 try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);
802 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");804 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
...@@ -1316,7 +1318,7 @@ fn transForLoop(...@@ -1316,7 +1318,7 @@ fn transForLoop(
1316 var block = false;1318 var block = false;
1317 var block_scope: ?*Scope.Block = null;1319 var block_scope: ?*Scope.Block = null;
1318 if (ZigClangForStmt_getInit(stmt)) |init| {1320 if (ZigClangForStmt_getInit(stmt)) |init| {
1319 block_scope = try Scope.Block.init(rp.c, scope, false);1321 block_scope = try Scope.Block.init(rp.c, scope, null);
1320 block_scope.?.block_node = try transCreateNodeBlock(rp.c, null);1322 block_scope.?.block_node = try transCreateNodeBlock(rp.c, null);
1321 inner = &block_scope.?.base;1323 inner = &block_scope.?.base;
1322 _ = try transStmt(rp, inner, init, .unused, .r_value);1324 _ = try transStmt(rp, inner, init, .unused, .r_value);
...@@ -1803,7 +1805,7 @@ fn transCreateNodeAssign(...@@ -1803,7 +1805,7 @@ fn transCreateNodeAssign(
1803 // zig: break :x _tmp1805 // zig: break :x _tmp
1804 // zig: })1806 // zig: })
1805 _ = try appendToken(rp.c, .LParen, "(");1807 _ = try appendToken(rp.c, .LParen, "(");
1806 const block_scope = try Scope.Block.init(rp.c, scope, true);1808 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
1807 block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);1809 block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
1808 const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()});1810 const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()});
18091811
...@@ -2732,6 +2734,33 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,...@@ -2732,6 +2734,33 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
2732 return token_index;2734 return token_index;
2733}2735}
27342736
2737// TODO hook up with codegen
2738fn isZigPrimitiveType(name: []const u8) bool {
2739 if (name.len > 1 and std.mem.startsWith(u8, name, "u") or std.mem.startsWith(u8, name, "u")) {
2740 for (name[1..]) |c| {
2741 switch (c) {
2742 '0'...'9' => {},
2743 else => return false,
2744 }
2745 }
2746 return true;
2747 }
2748 // void is invalid in c so it doesn't need to be checked.
2749 return std.mem.eql(u8, name, "comptime_float") or
2750 std.mem.eql(u8, name, "comptime_int") or
2751 std.mem.eql(u8, name, "bool") or
2752 std.mem.eql(u8, name, "isize") or
2753 std.mem.eql(u8, name, "usize") or
2754 std.mem.eql(u8, name, "f16") or
2755 std.mem.eql(u8, name, "f32") or
2756 std.mem.eql(u8, name, "f64") or
2757 std.mem.eql(u8, name, "f128") or
2758 std.mem.eql(u8, name, "c_longdouble") or
2759 std.mem.eql(u8, name, "noreturn") or
2760 std.mem.eql(u8, name, "type") or
2761 std.mem.eql(u8, name, "anyerror");
2762}
2763
2735fn isValidZigIdentifier(name: []const u8) bool {2764fn isValidZigIdentifier(name: []const u8) bool {
2736 for (name) |c, i| {2765 for (name) |c, i| {
2737 switch (c) {2766 switch (c) {
...@@ -2782,27 +2811,31 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {...@@ -2782,27 +2811,31 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
2782 const begin_loc = ZigClangMacroDefinitionRecord_getSourceRange_getBegin(macro);2811 const begin_loc = ZigClangMacroDefinitionRecord_getSourceRange_getBegin(macro);
27832812
2784 const name = try c.str(raw_name);2813 const name = try c.str(raw_name);
2785 if (scope.contains(name)) {2814
2815 // TODO https://github.com/ziglang/zig/issues/3756
2816 // TODO https://github.com/ziglang/zig/issues/1802
2817 const checked_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.a(), "_{}", .{name}) else name;
2818 if (scope.contains(checked_name)) {
2786 continue;2819 continue;
2787 }2820 }
2788 const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc);2821 const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc);
2789 ctok.tokenizeCMacro(&tok_list, begin_c) catch |err| switch (err) {2822 ctok.tokenizeCMacro(&tok_list, begin_c) catch |err| switch (err) {
2790 error.OutOfMemory => |e| return e,2823 error.OutOfMemory => |e| return e,
2791 else => {2824 else => {
2792 try failDecl(c, begin_loc, name, "unable to tokenize macro definition", .{});2825 try failDecl(c, begin_loc, checked_name, "unable to tokenize macro definition", .{});
2793 continue;2826 continue;
2794 },2827 },
2795 };2828 };
27962829
2797 var tok_it = tok_list.iterator(0);2830 var tok_it = tok_list.iterator(0);
2798 const first_tok = tok_it.next().?;2831 const first_tok = tok_it.next().?;
2799 assert(first_tok.id == .Identifier and std.mem.eql(u8, first_tok.bytes, name));2832 assert(first_tok.id == .Identifier and std.mem.eql(u8, first_tok.bytes, checked_name));
2800 const next = tok_it.peek().?;2833 const next = tok_it.peek().?;
2801 switch (next.id) {2834 switch (next.id) {
2802 .Identifier => {2835 .Identifier => {
2803 // if it equals itself, ignore. for example, from stdio.h:2836 // if it equals itself, ignore. for example, from stdio.h:
2804 // #define stdin stdin2837 // #define stdin stdin
2805 if (std.mem.eql(u8, name, next.bytes)) {2838 if (std.mem.eql(u8, checked_name, next.bytes)) {
2806 continue;2839 continue;
2807 }2840 }
2808 },2841 },
...@@ -2819,12 +2852,12 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {...@@ -2819,12 +2852,12 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
2819 } else false;2852 } else false;
28202853
2821 (if (macro_fn)2854 (if (macro_fn)
2822 transMacroFnDefine(c, &tok_it, name, begin_loc)2855 transMacroFnDefine(c, &tok_it, checked_name, begin_loc)
2823 else2856 else
2824 transMacroDefine(c, &tok_it, name, begin_loc)) catch |err| switch (err) {2857 transMacroDefine(c, &tok_it, checked_name, begin_loc)) catch |err| switch (err) {
2825 error.UnsupportedTranslation,2858 error.UnsupportedTranslation,
2826 error.ParseError,2859 error.ParseError,
2827 => try failDecl(c, begin_loc, name, "unable to translate macro", .{}),2860 => try failDecl(c, begin_loc, checked_name, "unable to translate macro", .{}),
2828 error.OutOfMemory => |e| return e,2861 error.OutOfMemory => |e| return e,
2829 };2862 };
2830 },2863 },
test/translate_c.zig+12-6
...@@ -724,10 +724,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -724,10 +724,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
724 \\pub export fn foo(c: u8) c_int {724 \\pub export fn foo(c: u8) c_int {
725 \\ var a: c_int = undefined;725 \\ var a: c_int = undefined;
726 \\ var b: c_int = undefined;726 \\ var b: c_int = undefined;
727 \\ a = blk_1: {727 \\ a = blk: {
728 \\ const _tmp_2 = 2;728 \\ const _tmp_1 = 2;
729 \\ b = _tmp_2;729 \\ b = _tmp_1;
730 \\ break :blk_1 _tmp_2;730 \\ break :blk _tmp_1;
731 \\ };731 \\ };
732 \\}732 \\}
733 });733 });
...@@ -746,9 +746,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -746,9 +746,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
746 \\ if (2 != 0) {746 \\ if (2 != 0) {
747 \\ var a: c_int = 2;747 \\ var a: c_int = 2;
748 \\ }748 \\ }
749 \\ if ((blk_1: {749 \\ if ((blk: {
750 \\ _ = 2;750 \\ _ = 2;
751 \\ break :blk_1 5;751 \\ break :blk 5;
752 \\ }) != 0) {752 \\ }) != 0) {
753 \\ var a: c_int = 2;753 \\ var a: c_int = 2;
754 \\ }754 \\ }
...@@ -819,6 +819,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -819,6 +819,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
819 \\}819 \\}
820 });820 });
821821
822 cases.add_2("shadowing primitive types",
823 \\unsigned anyerror = 2;
824 , &[_][]const u8{
825 \\pub export var _anyerror: c_uint = @as(c_uint, 2);
826 });
827
822 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////828 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
823829
824 if (builtin.os != builtin.Os.windows) {830 if (builtin.os != builtin.Os.windows) {