authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-16 15:59:35+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-16 18:19:37+02:00
log626562555e3ffd9ae259aba967efb23ce293e338
treee34acd8ace4fd6229ee333174e832607793f9527
parentd9527edfe0f017cd397de7ed947e47600092f929
signature Commit is signed but in an unrecognized format.

translate-c-2 wors-case assign


2 files changed, 111 insertions(+), 180 deletions(-)

src-self-hosted/translate_c.zig+93-180
......@@ -524,35 +524,18 @@ fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Err
524524
525525 const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
526526 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), typedef_name);
527 const name_tok = try appendIdentifier(c, typedef_name);
528 const eq_tok = try appendToken(c, .Equal, "=");
527 const node = try transCreateNodeVarDecl(c, true, true, typedef_name);
528 node.eq_token = try appendToken(c, .Equal, "=");
529529
530530 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
531531 const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);
532 const type_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
532 node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
533533 error.UnsupportedType => {
534534 return failDecl(c, typedef_loc, typedef_name, "unable to resolve typedef child type", .{});
535535 },
536536 error.OutOfMemory => |e| return e,
537537 };
538
539 const node = try c.a().create(ast.Node.VarDecl);
540 node.* = ast.Node.VarDecl{
541 .doc_comments = null,
542 .visib_token = visib_tok,
543 .thread_local_token = null,
544 .name_token = name_tok,
545 .eq_token = eq_tok,
546 .mut_token = const_tok,
547 .comptime_token = null,
548 .extern_export_token = null,
549 .lib_name = null,
550 .type_node = null,
551 .align_node = null,
552 .section_node = null,
553 .init_node = type_node,
554 .semicolon_token = try appendToken(c, .Semicolon, ";"),
555 };
538 node.semicolon_token = try appendToken(c, .Semicolon, ";");
556539 try addTopLevelDecl(c, typedef_name, &node.base);
557540}
558541
......@@ -572,69 +555,29 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!
572555 if (ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) or bare_name.len == 0)
573556 return;
574557
575 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
576 const const_tok = try appendToken(c, .Keyword_const, "const");
577
578558 const name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name });
579559 _ = try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), name);
580 const name_tok = try appendIdentifier(c, name);
581560
582 const eq_tok = try appendToken(c, .Equal, "=");
583 const init_node = transRecordDecl(c, record_decl) catch |err| switch (err) {
561 const node = try transCreateNodeVarDecl(c, true, true, name);
562
563 node.eq_token = try appendToken(c, .Equal, "=");
564 node.init_node = transRecordDecl(c, record_decl) catch |err| switch (err) {
584565 error.UnsupportedType => {
585566 return failDecl(c, ZigClangRecordDecl_getLocation(record_decl), name, "unable to resolve record type", .{});
586567 },
587568 error.OutOfMemory => |e| return e,
588569 };
589 const semicolon_token = try appendToken(c, .Semicolon, ";");
590
591 const node = try c.a().create(ast.Node.VarDecl);
592 node.* = ast.Node.VarDecl{
593 .doc_comments = null,
594 .visib_token = visib_tok,
595 .thread_local_token = null,
596 .name_token = name_tok,
597 .eq_token = eq_tok,
598 .mut_token = const_tok,
599 .comptime_token = null,
600 .extern_export_token = null,
601 .lib_name = null,
602 .type_node = null,
603 .align_node = null,
604 .section_node = null,
605 .init_node = init_node,
606 .semicolon_token = semicolon_token,
607 };
570 node.semicolon_token = try appendToken(c, .Semicolon, ";");
608571
609572 try addTopLevelDecl(c, name, &node.base);
610573 try c.alias_list.push(.{ .alias = bare_name, .name = name });
611574}
612575
613576fn createAlias(c: *Context, alias: var) !void {
614 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
615 const mut_tok = try appendToken(c, .Keyword_const, "const");
616 const name_tok = try appendIdentifier(c, alias.alias);
617
618 const eq_tok = try appendToken(c, .Equal, "=");
619 const init_node = try transCreateNodeIdentifier(c, alias.name);
620
621 const node = try c.a().create(ast.Node.VarDecl);
622 node.* = ast.Node.VarDecl{
623 .doc_comments = null,
624 .visib_token = visib_tok,
625 .thread_local_token = null,
626 .name_token = name_tok,
627 .eq_token = eq_tok,
628 .mut_token = mut_tok,
629 .comptime_token = null,
630 .extern_export_token = null,
631 .lib_name = null,
632 .type_node = null,
633 .align_node = null,
634 .section_node = null,
635 .init_node = init_node,
636 .semicolon_token = try appendToken(c, .Semicolon, ";"),
637 };
577 const node = try transCreateNodeVarDecl(c, true, true, alias.alias);
578 node.eq_token = try appendToken(c, .Equal, "=");
579 node.init_node = try transCreateNodeIdentifier(c, alias.name);
580 node.semicolon_token = try appendToken(c, .Semicolon, ";");
638581 return addTopLevelDecl(c, alias.alias, &node.base);
639582}
640583
......@@ -697,7 +640,7 @@ fn transBinaryOperator(
697640 "TODO: handle more C binary operators: {}",
698641 .{op},
699642 ),
700 .Assign => return &(try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt))).base,
643 .Assign => return try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt)),
701644 .Add => {
702645 const node = if (cIsUnsignedInteger(qt))
703646 try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%", true)
......@@ -782,6 +725,7 @@ fn transBinaryOperator(
782725 const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
783726 if (block_scope.base.parent == scope) {
784727 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
728 break_node.rhs = rhs;
785729 _ = try appendToken(rp.c, .Semicolon, ";");
786730 try block_scope.block_node.statements.push(&break_node.base);
787731 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
......@@ -862,10 +806,6 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
862806 else
863807 try appendToken(c, .Keyword_threadlocal, "threadlocal");
864808 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
865 const mut_token = if (ZigClangQualType_isConstQualified(qual_type))
866 try appendToken(c, .Keyword_const, "const")
867 else
868 try appendToken(c, .Keyword_var, "var");
869809 const name = try c.str(ZigClangDecl_getName_bytes_begin(
870810 @ptrCast(*const ZigClangDecl, var_decl),
871811 ));
......@@ -873,36 +813,18 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
873813 try block_scope.variables.push(.{ .name = name, .alias = a });
874814 break :blk a;
875815 } else name;
876 const name_token = try appendIdentifier(c, checked_name);
816 const node = try transCreateNodeVarDecl(c, false, ZigClangQualType_isConstQualified(qual_type), checked_name);
877817
878 const colon_token = try appendToken(c, .Colon, ":");
818 _ = try appendToken(c, .Colon, ":");
879819 const loc = ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt));
880 const type_node = try transQualType(rp, qual_type, loc);
820 node.type_node = try transQualType(rp, qual_type, loc);
881821
882 const eq_token = try appendToken(c, .Equal, "=");
883 const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|
822 node.eq_token = try appendToken(c, .Equal, "=");
823 node.init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|
884824 try transExpr(rp, scope, expr, .used, .r_value)
885825 else
886826 try transCreateNodeUndefinedLiteral(c);
887 const semicolon_token = try appendToken(c, .Semicolon, ";");
888
889 const node = try c.a().create(ast.Node.VarDecl);
890 node.* = ast.Node.VarDecl{
891 .doc_comments = null,
892 .visib_token = null,
893 .thread_local_token = thread_local_token,
894 .name_token = name_token,
895 .eq_token = eq_token,
896 .mut_token = mut_token,
897 .comptime_token = null,
898 .extern_export_token = null,
899 .lib_name = null,
900 .type_node = type_node,
901 .align_node = null, // TODO ?*Node,
902 .section_node = null,
903 .init_node = init_node,
904 .semicolon_token = semicolon_token,
905 };
827 node.semicolon_token = try appendToken(c, .Semicolon, ";");
906828 try block_scope.block_node.statements.push(&node.base);
907829 },
908830 else => |kind| return revertAndWarn(
......@@ -1395,9 +1317,6 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
13951317 const rp = makeRestorePoint(c);
13961318 const enum_loc = ZigClangEnumDecl_getLocation(enum_decl);
13971319
1398 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
1399 const const_tok = try appendToken(c, .Keyword_const, "const");
1400
14011320 var bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_decl)));
14021321 var is_unnamed = false;
14031322 if (bare_name.len == 0) {
......@@ -1407,10 +1326,10 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
14071326
14081327 const name = try std.fmt.allocPrint(c.a(), "enum_{}", .{bare_name});
14091328 _ = try c.decl_table.put(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)), name);
1410 const name_tok = try appendIdentifier(c, name);
1411 const eq_tok = try appendToken(c, .Equal, "=");
1329 const node = try transCreateNodeVarDecl(c, true, true, name);
1330 node.eq_token = try appendToken(c, .Equal, "=");
14121331
1413 const init_node = if (ZigClangEnumDecl_getDefinition(enum_decl)) |enum_def| blk: {
1332 node.init_node = if (ZigClangEnumDecl_getDefinition(enum_decl)) |enum_def| blk: {
14141333 var pure_enum = true;
14151334 var it = ZigClangEnumDecl_enumerator_begin(enum_def);
14161335 var end_it = ZigClangEnumDecl_enumerator_end(enum_def);
......@@ -1504,25 +1423,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
15041423 } else
15051424 try transCreateNodeOpaqueType(c);
15061425
1507 const semicolon_token = try appendToken(c, .Semicolon, ";");
1508
1509 const node = try c.a().create(ast.Node.VarDecl);
1510 node.* = ast.Node.VarDecl{
1511 .visib_token = visib_tok,
1512 .mut_token = const_tok,
1513 .name_token = name_tok,
1514 .eq_token = eq_tok,
1515 .init_node = init_node,
1516 .semicolon_token = semicolon_token,
1517 .doc_comments = null,
1518 .comptime_token = null,
1519 .extern_export_token = null,
1520 .thread_local_token = null,
1521 .lib_name = null,
1522 .type_node = null,
1523 .align_node = null,
1524 .section_node = null,
1525 };
1426 node.semicolon_token = try appendToken(c, .Semicolon, ";");
15261427
15271428 try addTopLevelDecl(c, name, &node.base);
15281429 if (!is_unnamed)
......@@ -1531,14 +1432,12 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
15311432}
15321433
15331434fn addEnumTopLevel(c: *Context, enum_name: []const u8, field_name: []const u8, enum_val_name: []const u8) !void {
1534 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
1535 const const_tok = try appendToken(c, .Keyword_const, "const");
1536 const name_tok = try appendIdentifier(c, enum_val_name);
1537 const eq_tok = try appendToken(c, .Equal, "=");
1538
1435 const node = try transCreateNodeVarDecl(c, true, true, enum_val_name);
1436 node.eq_token = try appendToken(c, .Equal, "=");
15391437 const enum_ident = try transCreateNodeIdentifier(c, enum_name);
15401438 const period_tok = try appendToken(c, .Period, ".");
15411439 const field_ident = try transCreateNodeIdentifier(c, field_name);
1440 node.semicolon_token = try appendToken(c, .Semicolon, ";");
15421441
15431442 const field_access_node = try c.a().create(ast.Node.InfixOp);
15441443 field_access_node.* = .{
......@@ -1547,26 +1446,7 @@ fn addEnumTopLevel(c: *Context, enum_name: []const u8, field_name: []const u8, e
15471446 .op = .Period,
15481447 .rhs = field_ident,
15491448 };
1550 const semicolon_token = try appendToken(c, .Semicolon, ";");
1551
1552 const node = try c.a().create(ast.Node.VarDecl);
1553 node.* = ast.Node.VarDecl{
1554 .visib_token = visib_tok,
1555 .mut_token = const_tok,
1556 .name_token = name_tok,
1557 .eq_token = eq_tok,
1558 .init_node = &field_access_node.base,
1559 .semicolon_token = semicolon_token,
1560 .thread_local_token = null,
1561 .doc_comments = null,
1562 .comptime_token = null,
1563 .extern_export_token = null,
1564 .lib_name = null,
1565 .type_node = null,
1566 .align_node = null,
1567 .section_node = null,
1568 };
1569
1449 node.init_node = &field_access_node.base;
15701450 try addTopLevelDecl(c, field_name, &node.base);
15711451}
15721452
......@@ -1693,7 +1573,7 @@ fn transCreateNodeAssign(
16931573 result_used: ResultUsed,
16941574 lhs: *const ZigClangExpr,
16951575 rhs: *const ZigClangExpr,
1696) !*ast.Node.InfixOp {
1576) !*ast.Node {
16971577 // common case
16981578 // c: lhs = rhs
16991579 // zig: lhs = rhs
......@@ -1710,7 +1590,7 @@ fn transCreateNodeAssign(
17101590 .op = .Assign,
17111591 .rhs = rhs_node,
17121592 };
1713 return node;
1593 return &node.base;
17141594 }
17151595
17161596 // worst case
......@@ -1720,13 +1600,39 @@ fn transCreateNodeAssign(
17201600 // zig: lhs = _tmp;
17211601 // zig: break :x _tmp
17221602 // zig: })
1723 return revertAndWarn(
1724 rp,
1725 error.UnsupportedTranslation,
1726 ZigClangExpr_getBeginLoc(lhs),
1727 "TODO: worst case assign op expr",
1728 .{},
1729 );
1603 _ = try appendToken(rp.c, .LParen, "(");
1604 const block_scope = try Scope.Block.init(rp.c, scope, true);
1605 const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()});
1606
1607 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
1608 node.eq_token = try appendToken(rp.c, .Equal, "=");
1609 node.init_node = try transExpr(rp, scope, rhs, .used, .r_value);
1610 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
1611 try block_scope.block_node.statements.push(&node.base);
1612
1613 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
1614 const eq_token = try appendToken(rp.c, .Equal, "=");
1615 const ident = try transCreateNodeIdentifier(rp.c, tmp);
1616 _ = try appendToken(rp.c, .Semicolon, ";");
1617
1618 const assign = try rp.c.a().create(ast.Node.InfixOp);
1619 assign.* = .{
1620 .op_token = eq_token,
1621 .lhs = lhs_node,
1622 .op = .Assign,
1623 .rhs = ident,
1624 };
1625 try block_scope.block_node.statements.push(&assign.base);
1626
1627 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
1628 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
1629 _ = try appendToken(rp.c, .Semicolon, ";");
1630 try block_scope.block_node.statements.push(&break_node.base);
1631 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
1632 // semicolon must immediately follow rbrace because it is the last token in a block
1633 _ = try appendToken(rp.c, .Semicolon, ";");
1634 _ = try appendToken(rp.c, .RParen, ")");
1635 return &block_scope.block_node.base;
17301636}
17311637
17321638fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall {
......@@ -2091,6 +1997,31 @@ fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowE
20911997 return node;
20921998}
20931999
2000fn transCreateNodeVarDecl(c: *Context, is_pub: bool, is_const: bool, name: []const u8) !*ast.Node.VarDecl {
2001 const visib_tok = if (is_pub) try appendToken(c, .Keyword_pub, "pub") else null;
2002 const mut_tok = if (is_const) try appendToken(c, .Keyword_const, "const") else try appendToken(c, .Keyword_var, "var");
2003 const name_tok = try appendIdentifier(c, name);
2004
2005 const node = try c.a().create(ast.Node.VarDecl);
2006 node.* = ast.Node.VarDecl{
2007 .doc_comments = null,
2008 .visib_token = visib_tok,
2009 .thread_local_token = null,
2010 .name_token = name_tok,
2011 .eq_token = undefined,
2012 .mut_token = mut_tok,
2013 .comptime_token = null,
2014 .extern_export_token = null,
2015 .lib_name = null,
2016 .type_node = null,
2017 .align_node = null,
2018 .section_node = null,
2019 .init_node = null,
2020 .semicolon_token = undefined,
2021 };
2022 return node;
2023}
2024
20942025const RestorePoint = struct {
20952026 c: *Context,
20962027 token_index: ast.TokenIndex,
......@@ -2673,30 +2604,12 @@ fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8,
26732604 const rp = makeRestorePoint(c);
26742605 const scope = &c.global_scope.base;
26752606
2676 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
2677 const mut_tok = try appendToken(c, .Keyword_const, "const");
2678 const name_tok = try appendIdentifier(c, name);
2679 const eq_tok = try appendToken(c, .Equal, "=");
2607 const node = try transCreateNodeVarDecl(c, true, true, name);
2608 node.eq_token = try appendToken(c, .Equal, "=");
26802609
2681 const init_node = try parseCExpr(rp, it, source_loc, scope);
2610 node.init_node = try parseCExpr(rp, it, source_loc, scope);
26822611
2683 const node = try c.a().create(ast.Node.VarDecl);
2684 node.* = ast.Node.VarDecl{
2685 .doc_comments = null,
2686 .visib_token = visib_tok,
2687 .thread_local_token = null,
2688 .name_token = name_tok,
2689 .eq_token = eq_tok,
2690 .mut_token = mut_tok,
2691 .comptime_token = null,
2692 .extern_export_token = null,
2693 .lib_name = null,
2694 .type_node = null,
2695 .align_node = null,
2696 .section_node = null,
2697 .init_node = init_node,
2698 .semicolon_token = try appendToken(c, .Semicolon, ";"),
2699 };
2612 node.semicolon_token = try appendToken(c, .Semicolon, ";");
27002613 _ = try c.global_scope.macro_table.put(name, &node.base);
27012614}
27022615
test/translate_c.zig+18
......@@ -714,6 +714,24 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
714714 \\}
715715 });
716716
717 cases.add_2("wors-case assign",
718 \\int foo(char c) {
719 \\ int a;
720 \\ int b;
721 \\ a = b = 2;
722 \\}
723 , &[_][]const u8{
724 \\pub export fn foo(c: u8) c_int {
725 \\ var a: c_int = undefined;
726 \\ var b: c_int = undefined;
727 \\ a = blk_1: {
728 \\ const _tmp_2 = 2;
729 \\ b = _tmp_2;
730 \\ break :blk_1 _tmp_2;
731 \\ };
732 \\}
733 });
734
717735 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
718736
719737 if (builtin.os != builtin.Os.windows) {