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 {
6969 label: ?[]const u8,
7070
7171 /// Don't forget to set rbrace token and block_node later
72 fn init(c: *Context, parent: *Scope, want_label: bool) !*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;
72 fn init(c: *Context, parent: *Scope, label: ?[]const u8) !*Block {
7573 const block = try c.a().create(Block);
7674 block.* = .{
7775 .base = .{
......@@ -171,7 +169,7 @@ const Scope = struct {
171169 .Condition => {
172170 const cond = @fieldParentPtr(Condition, "base", scope);
173171 // comma operator used
174 return try Block.init(c, scope, true);
172 return try Block.init(c, scope, "blk");
175173 },
176174 else => scope = scope.parent.?,
177175 }
......@@ -179,7 +177,7 @@ const Scope = struct {
179177 }
180178
181179 fn createAlias(scope: *Scope, c: *Context, name: []const u8) !?[]const u8 {
182 if (scope.contains(name)) {
180 if (isZigPrimitiveType(name) or scope.contains(name)) {
183181 return try std.fmt.allocPrint(c.a(), "{}_{}", .{ name, c.getMangle() });
184182 }
185183 return null;
......@@ -452,7 +450,11 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
452450
453451 const scope = &c.global_scope.base;
454452 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);
456458 const var_decl_loc = ZigClangVarDecl_getLocation(var_decl);
457459
458460 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
......@@ -471,12 +473,12 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
471473 else
472474 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
476478 _ = try appendToken(c, .Colon, ":");
477479 const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) {
478480 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", .{});
480482 },
481483 error.OutOfMemory => |e| return e,
482484 };
......@@ -491,14 +493,14 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
491493 error.UnsupportedTranslation,
492494 error.UnsupportedType,
493495 => {
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", .{});
495497 },
496498 error.OutOfMemory => |e| return e,
497499 }
498500 else
499501 try transCreateNodeUndefinedLiteral(c);
500502 } 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", .{});
502504 }
503505
504506 const node = try c.a().create(ast.Node.VarDecl);
......@@ -518,7 +520,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
518520 .init_node = init_node,
519521 .semicolon_token = try appendToken(c, .Semicolon, ";"),
520522 };
521 return addTopLevelDecl(c, var_name, &node.base);
523 return addTopLevelDecl(c, checked_name, &node.base);
522524}
523525
524526fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!void {
......@@ -796,7 +798,7 @@ fn transCompoundStmtInline(
796798}
797799
798800fn 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);
800802 block_scope.block_node = try transCreateNodeBlock(rp.c, null);
801803 try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);
802804 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
......@@ -1316,7 +1318,7 @@ fn transForLoop(
13161318 var block = false;
13171319 var block_scope: ?*Scope.Block = null;
13181320 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);
13201322 block_scope.?.block_node = try transCreateNodeBlock(rp.c, null);
13211323 inner = &block_scope.?.base;
13221324 _ = try transStmt(rp, inner, init, .unused, .r_value);
......@@ -1803,7 +1805,7 @@ fn transCreateNodeAssign(
18031805 // zig: break :x _tmp
18041806 // zig: })
18051807 _ = 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");
18071809 block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
18081810 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,
27322734 return token_index;
27332735}
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
27352764fn isValidZigIdentifier(name: []const u8) bool {
27362765 for (name) |c, i| {
27372766 switch (c) {
......@@ -2782,27 +2811,31 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
27822811 const begin_loc = ZigClangMacroDefinitionRecord_getSourceRange_getBegin(macro);
27832812
27842813 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)) {
27862819 continue;
27872820 }
27882821 const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc);
27892822 ctok.tokenizeCMacro(&tok_list, begin_c) catch |err| switch (err) {
27902823 error.OutOfMemory => |e| return e,
27912824 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", .{});
27932826 continue;
27942827 },
27952828 };
27962829
27972830 var tok_it = tok_list.iterator(0);
27982831 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));
28002833 const next = tok_it.peek().?;
28012834 switch (next.id) {
28022835 .Identifier => {
28032836 // if it equals itself, ignore. for example, from stdio.h:
28042837 // #define stdin stdin
2805 if (std.mem.eql(u8, name, next.bytes)) {
2838 if (std.mem.eql(u8, checked_name, next.bytes)) {
28062839 continue;
28072840 }
28082841 },
......@@ -2819,12 +2852,12 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
28192852 } else false;
28202853
28212854 (if (macro_fn)
2822 transMacroFnDefine(c, &tok_it, name, begin_loc)
2855 transMacroFnDefine(c, &tok_it, checked_name, begin_loc)
28232856 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) {
28252858 error.UnsupportedTranslation,
28262859 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", .{}),
28282861 error.OutOfMemory => |e| return e,
28292862 };
28302863 },
test/translate_c.zig+12-6
......@@ -724,10 +724,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
724724 \\pub export fn foo(c: u8) c_int {
725725 \\ var a: c_int = undefined;
726726 \\ var b: c_int = undefined;
727 \\ a = blk_1: {
728 \\ const _tmp_2 = 2;
729 \\ b = _tmp_2;
730 \\ break :blk_1 _tmp_2;
727 \\ a = blk: {
728 \\ const _tmp_1 = 2;
729 \\ b = _tmp_1;
730 \\ break :blk _tmp_1;
731731 \\ };
732732 \\}
733733 });
......@@ -746,9 +746,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
746746 \\ if (2 != 0) {
747747 \\ var a: c_int = 2;
748748 \\ }
749 \\ if ((blk_1: {
749 \\ if ((blk: {
750750 \\ _ = 2;
751 \\ break :blk_1 5;
751 \\ break :blk 5;
752752 \\ }) != 0) {
753753 \\ var a: c_int = 2;
754754 \\ }
......@@ -819,6 +819,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
819819 \\}
820820 });
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
822828 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
823829
824830 if (builtin.os != builtin.Os.windows) {