| ... | ... | @@ -45,26 +45,26 @@ const Scope = struct { |
| 45 | 45 | |
| 46 | 46 | const Id = enum { |
| 47 | 47 | Switch, |
| 48 | | Var, |
| 49 | 48 | Block, |
| 50 | 49 | Root, |
| 51 | 50 | While, |
| 52 | 51 | FnDef, |
| 52 | Ref, |
| 53 | 53 | }; |
| 54 | 54 | |
| 55 | 55 | const Switch = struct { |
| 56 | 56 | base: Scope, |
| 57 | 57 | }; |
| 58 | 58 | |
| 59 | | const Var = struct { |
| 59 | /// used when getting a member `a.b` |
| 60 | const Ref = struct { |
| 60 | 61 | base: Scope, |
| 61 | | c_name: []const u8, |
| 62 | | zig_name: []const u8, |
| 63 | 62 | }; |
| 64 | 63 | |
| 65 | 64 | const Block = struct { |
| 66 | 65 | base: Scope, |
| 67 | 66 | block_node: *ast.Node.Block, |
| 67 | variables: AliasList, |
| 68 | 68 | |
| 69 | 69 | /// Don't forget to set rbrace token later |
| 70 | 70 | fn init(c: *Context, parent: *Scope, block_node: *ast.Node.Block) !*Block { |
| ... | ... | @@ -75,9 +75,28 @@ const Scope = struct { |
| 75 | 75 | .parent = parent, |
| 76 | 76 | }, |
| 77 | 77 | .block_node = block_node, |
| 78 | .variables = AliasList.init(c.a()), |
| 78 | 79 | }; |
| 79 | 80 | return block; |
| 80 | 81 | } |
| 82 | |
| 83 | fn getAlias(scope: *Block, name: []const u8) ?[]const u8 { |
| 84 | var it = scope.variables.iterator(0); |
| 85 | while (it.next()) |p| { |
| 86 | if (std.mem.eql(u8, p.name, name)) |
| 87 | return p.alias; |
| 88 | } |
| 89 | return scope.base.parent.?.getAlias(name); |
| 90 | } |
| 91 | |
| 92 | fn contains(scope: *Block, name: []const u8) bool { |
| 93 | var it = scope.variables.iterator(0); |
| 94 | while (it.next()) |p| { |
| 95 | if (std.mem.eql(u8, p.name, name)) |
| 96 | return true; |
| 97 | } |
| 98 | return scope.base.parent.?.contains(name); |
| 99 | } |
| 81 | 100 | }; |
| 82 | 101 | |
| 83 | 102 | const Root = struct { |
| ... | ... | @@ -155,26 +174,24 @@ const Scope = struct { |
| 155 | 174 | fn getAlias(scope: *Scope, name: []const u8) ?[]const u8 { |
| 156 | 175 | return switch (scope.id) { |
| 157 | 176 | .Root => null, |
| 177 | .Ref => null, |
| 158 | 178 | .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name), |
| 179 | .Block => @fieldParentPtr(Block, "base", scope).getAlias(name), |
| 159 | 180 | else => @panic("TODO Scope.getAlias"), |
| 160 | 181 | }; |
| 161 | 182 | } |
| 162 | 183 | |
| 163 | 184 | fn contains(scope: *Scope, name: []const u8) bool { |
| 164 | 185 | return switch (scope.id) { |
| 186 | .Ref => false, |
| 165 | 187 | .Root => @fieldParentPtr(Root, "base", scope).contains(name), |
| 166 | 188 | .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name), |
| 189 | .Block => @fieldParentPtr(Block, "base", scope).contains(name), |
| 167 | 190 | else => @panic("TODO Scope.contains"), |
| 168 | 191 | }; |
| 169 | 192 | } |
| 170 | 193 | }; |
| 171 | 194 | |
| 172 | | const TransResult = struct { |
| 173 | | node: *ast.Node, |
| 174 | | node_scope: *Scope, |
| 175 | | child_scope: *Scope, |
| 176 | | }; |
| 177 | | |
| 178 | 195 | const Context = struct { |
| 179 | 196 | tree: *ast.Tree, |
| 180 | 197 | source_buffer: *std.Buffer, |
| ... | ... | @@ -388,14 +405,14 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 388 | 405 | |
| 389 | 406 | // actual function definition with body |
| 390 | 407 | const body_stmt = ZigClangFunctionDecl_getBody(fn_decl); |
| 391 | | const result = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) { |
| 408 | const body_node = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) { |
| 392 | 409 | error.OutOfMemory => |e| return e, |
| 393 | 410 | error.UnsupportedTranslation, |
| 394 | 411 | error.UnsupportedType, |
| 395 | 412 | => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}), |
| 396 | 413 | }; |
| 397 | | assert(result.node.id == ast.Node.Id.Block); |
| 398 | | proto_node.body_node = result.node; |
| 414 | assert(body_node.id == .Block); |
| 415 | proto_node.body_node = body_node; |
| 399 | 416 | |
| 400 | 417 | return addTopLevelDecl(c, fn_name, &proto_node.base); |
| 401 | 418 | } |
| ... | ... | @@ -431,7 +448,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 431 | 448 | else |
| 432 | 449 | try appendToken(c, .Keyword_var, "var"); |
| 433 | 450 | |
| 434 | | const name_tok = try appendIdentifier(c, var_name, null); |
| 451 | const name_tok = try appendIdentifier(c, var_name); |
| 435 | 452 | |
| 436 | 453 | _ = try appendToken(c, .Colon, ":"); |
| 437 | 454 | const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) { |
| ... | ... | @@ -446,17 +463,16 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 446 | 463 | |
| 447 | 464 | if (ZigClangVarDecl_hasInit(var_decl)) { |
| 448 | 465 | eq_tok = try appendToken(c, .Equal, "="); |
| 449 | | init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| blk: { |
| 450 | | var res = transExpr(rp, &c.global_scope.base, expr, .used, .r_value) catch |err| switch (err) { |
| 466 | init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| |
| 467 | transExpr(rp, &c.global_scope.base, expr, .used, .r_value) catch |err| switch (err) { |
| 451 | 468 | error.UnsupportedTranslation, |
| 452 | 469 | error.UnsupportedType, |
| 453 | 470 | => { |
| 454 | 471 | return failDecl(c, var_decl_loc, var_name, "unable to translate initializer", .{}); |
| 455 | 472 | }, |
| 456 | 473 | error.OutOfMemory => |e| return e, |
| 457 | | }; |
| 458 | | break :blk res.node; |
| 459 | | } else |
| 474 | } |
| 475 | else |
| 460 | 476 | try transCreateNodeUndefinedLiteral(c); |
| 461 | 477 | } else if (storage_class != .Extern) { |
| 462 | 478 | return failDecl(c, var_decl_loc, var_name, "non-extern variable has no initializer", .{}); |
| ... | ... | @@ -492,7 +508,7 @@ fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Err |
| 492 | 508 | |
| 493 | 509 | const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl))); |
| 494 | 510 | _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), typedef_name); |
| 495 | | const name_tok = try appendIdentifier(c, typedef_name, null); |
| 511 | const name_tok = try appendIdentifier(c, typedef_name); |
| 496 | 512 | const eq_tok = try appendToken(c, .Equal, "="); |
| 497 | 513 | |
| 498 | 514 | const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); |
| ... | ... | @@ -545,7 +561,7 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error! |
| 545 | 561 | |
| 546 | 562 | const name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name }); |
| 547 | 563 | _ = try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), name); |
| 548 | | const name_tok = try appendIdentifier(c, name, null); |
| 564 | const name_tok = try appendIdentifier(c, name); |
| 549 | 565 | |
| 550 | 566 | const eq_tok = try appendToken(c, .Equal, "="); |
| 551 | 567 | const init_node = transRecordDecl(c, record_decl) catch |err| switch (err) { |
| ... | ... | @@ -581,10 +597,10 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error! |
| 581 | 597 | fn createAlias(c: *Context, alias: var) !void { |
| 582 | 598 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 583 | 599 | const mut_tok = try appendToken(c, .Keyword_const, "const"); |
| 584 | | const name_tok = try appendIdentifier(c, alias.alias, null); |
| 600 | const name_tok = try appendIdentifier(c, alias.alias); |
| 585 | 601 | |
| 586 | 602 | const eq_tok = try appendToken(c, .Equal, "="); |
| 587 | | const init_node = try transCreateNodeIdentifier(c, alias.name, null); |
| 603 | const init_node = try transCreateNodeIdentifier(c, alias.name); |
| 588 | 604 | |
| 589 | 605 | const node = try c.a().create(ast.Node.VarDecl); |
| 590 | 606 | node.* = ast.Node.VarDecl{ |
| ... | ... | @@ -622,7 +638,7 @@ fn transStmt( |
| 622 | 638 | stmt: *const ZigClangStmt, |
| 623 | 639 | result_used: ResultUsed, |
| 624 | 640 | lrvalue: LRValue, |
| 625 | | ) TransError!TransResult { |
| 641 | ) TransError!*ast.Node { |
| 626 | 642 | const sc = ZigClangStmt_getStmtClass(stmt); |
| 627 | 643 | switch (sc) { |
| 628 | 644 | .BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used), |
| ... | ... | @@ -654,7 +670,7 @@ fn transBinaryOperator( |
| 654 | 670 | scope: *Scope, |
| 655 | 671 | stmt: *const ZigClangBinaryOperator, |
| 656 | 672 | result_used: ResultUsed, |
| 657 | | ) TransError!TransResult { |
| 673 | ) TransError!*ast.Node { |
| 658 | 674 | const op = ZigClangBinaryOperator_getOpcode(stmt); |
| 659 | 675 | const qt = ZigClangBinaryOperator_getType(stmt); |
| 660 | 676 | switch (op) { |
| ... | ... | @@ -665,67 +681,43 @@ fn transBinaryOperator( |
| 665 | 681 | "TODO: handle more C binary operators: {}", |
| 666 | 682 | .{op}, |
| 667 | 683 | ), |
| 668 | | .Assign => return TransResult{ |
| 669 | | .node = &(try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt))).base, |
| 670 | | .child_scope = scope, |
| 671 | | .node_scope = scope, |
| 672 | | }, |
| 684 | .Assign => return &(try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt))).base, |
| 673 | 685 | .Add => { |
| 674 | 686 | const node = if (cIsUnsignedInteger(qt)) |
| 675 | 687 | try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%", true) |
| 676 | 688 | else |
| 677 | 689 | try transCreateNodeInfixOp(rp, scope, stmt, .Add, .Plus, "+", true); |
| 678 | | return maybeSuppressResult(rp, scope, result_used, TransResult{ |
| 679 | | .node = node, |
| 680 | | .child_scope = scope, |
| 681 | | .node_scope = scope, |
| 682 | | }); |
| 690 | return maybeSuppressResult(rp, scope, result_used, node); |
| 683 | 691 | }, |
| 684 | 692 | .Sub => { |
| 685 | 693 | const node = if (cIsUnsignedInteger(qt)) |
| 686 | 694 | try transCreateNodeInfixOp(rp, scope, stmt, .SubWrap, .MinusPercent, "-%", true) |
| 687 | 695 | else |
| 688 | 696 | try transCreateNodeInfixOp(rp, scope, stmt, .Sub, .Minus, "-", true); |
| 689 | | return maybeSuppressResult(rp, scope, result_used, TransResult{ |
| 690 | | .node = node, |
| 691 | | .child_scope = scope, |
| 692 | | .node_scope = scope, |
| 693 | | }); |
| 697 | return maybeSuppressResult(rp, scope, result_used, node); |
| 694 | 698 | }, |
| 695 | 699 | .Mul => { |
| 696 | 700 | const node = if (cIsUnsignedInteger(qt)) |
| 697 | 701 | try transCreateNodeInfixOp(rp, scope, stmt, .MultWrap, .AsteriskPercent, "*%", true) |
| 698 | 702 | else |
| 699 | 703 | try transCreateNodeInfixOp(rp, scope, stmt, .Mult, .Asterisk, "*", true); |
| 700 | | return maybeSuppressResult(rp, scope, result_used, TransResult{ |
| 701 | | .node = node, |
| 702 | | .child_scope = scope, |
| 703 | | .node_scope = scope, |
| 704 | | }); |
| 704 | return maybeSuppressResult(rp, scope, result_used, node); |
| 705 | 705 | }, |
| 706 | 706 | .Div => { |
| 707 | 707 | if (!cIsUnsignedInteger(qt)) { |
| 708 | 708 | // signed integer division uses @divTrunc |
| 709 | 709 | const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc"); |
| 710 | 710 | const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); |
| 711 | | try div_trunc_node.params.push(lhs.node); |
| 711 | try div_trunc_node.params.push(lhs); |
| 712 | 712 | _ = try appendToken(rp.c, .Comma, ","); |
| 713 | 713 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 714 | | try div_trunc_node.params.push(rhs.node); |
| 714 | try div_trunc_node.params.push(rhs); |
| 715 | 715 | div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 716 | | return maybeSuppressResult(rp, scope, result_used, TransResult{ |
| 717 | | .node = &div_trunc_node.base, |
| 718 | | .child_scope = scope, |
| 719 | | .node_scope = scope, |
| 720 | | }); |
| 716 | return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base); |
| 721 | 717 | } else { |
| 722 | 718 | // unsigned/float division uses the operator |
| 723 | 719 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .Div, .Slash, "/", true); |
| 724 | | return maybeSuppressResult(rp, scope, result_used, TransResult{ |
| 725 | | .node = node, |
| 726 | | .child_scope = scope, |
| 727 | | .node_scope = scope, |
| 728 | | }); |
| 720 | return maybeSuppressResult(rp, scope, result_used, node); |
| 729 | 721 | } |
| 730 | 722 | }, |
| 731 | 723 | .Rem => { |
| ... | ... | @@ -733,24 +725,16 @@ fn transBinaryOperator( |
| 733 | 725 | // signed integer division uses @rem |
| 734 | 726 | const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem"); |
| 735 | 727 | const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); |
| 736 | | try rem_node.params.push(lhs.node); |
| 728 | try rem_node.params.push(lhs); |
| 737 | 729 | _ = try appendToken(rp.c, .Comma, ","); |
| 738 | 730 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 739 | | try rem_node.params.push(rhs.node); |
| 731 | try rem_node.params.push(rhs); |
| 740 | 732 | rem_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 741 | | return maybeSuppressResult(rp, scope, result_used, TransResult{ |
| 742 | | .node = &rem_node.base, |
| 743 | | .child_scope = scope, |
| 744 | | .node_scope = scope, |
| 745 | | }); |
| 733 | return maybeSuppressResult(rp, scope, result_used, &rem_node.base); |
| 746 | 734 | } else { |
| 747 | 735 | // unsigned/float division uses the operator |
| 748 | 736 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .Mod, .Percent, "%", true); |
| 749 | | return maybeSuppressResult(rp, scope, result_used, TransResult{ |
| 750 | | .node = node, |
| 751 | | .child_scope = scope, |
| 752 | | .node_scope = scope, |
| 753 | | }); |
| 737 | return maybeSuppressResult(rp, scope, result_used, node); |
| 754 | 738 | } |
| 755 | 739 | }, |
| 756 | 740 | .Shl, |
| ... | ... | @@ -793,33 +777,22 @@ fn transCompoundStmtInline( |
| 793 | 777 | parent_scope: *Scope, |
| 794 | 778 | stmt: *const ZigClangCompoundStmt, |
| 795 | 779 | block_node: *ast.Node.Block, |
| 796 | | ) TransError!TransResult { |
| 780 | ) TransError!void { |
| 797 | 781 | var it = ZigClangCompoundStmt_body_begin(stmt); |
| 798 | 782 | const end_it = ZigClangCompoundStmt_body_end(stmt); |
| 799 | | var scope = parent_scope; |
| 800 | 783 | while (it != end_it) : (it += 1) { |
| 801 | 784 | const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value); |
| 802 | | scope = result.child_scope; |
| 803 | | if (result.node != &block_node.base) |
| 804 | | try block_node.statements.push(result.node); |
| 785 | if (result != &block_node.base) |
| 786 | try block_node.statements.push(result); |
| 805 | 787 | } |
| 806 | | return TransResult{ |
| 807 | | .node = &block_node.base, |
| 808 | | .child_scope = scope, |
| 809 | | .node_scope = scope, |
| 810 | | }; |
| 811 | 788 | } |
| 812 | 789 | |
| 813 | | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!TransResult { |
| 814 | | const block_node = try transCreateNodeBlock(rp.c, null, null); |
| 790 | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node { |
| 791 | const block_node = try transCreateNodeBlock(rp.c, null); |
| 815 | 792 | const block_scope = try Scope.Block.init(rp.c, scope, block_node); |
| 816 | | const inline_result = try transCompoundStmtInline(rp, &block_scope.base, stmt, block_node); |
| 793 | try transCompoundStmtInline(rp, &block_scope.base, stmt, block_node); |
| 817 | 794 | block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 818 | | return TransResult{ |
| 819 | | .node = &block_node.base, |
| 820 | | .node_scope = inline_result.node_scope, |
| 821 | | .child_scope = inline_result.child_scope, |
| 822 | | }; |
| 795 | return &block_node.base; |
| 823 | 796 | } |
| 824 | 797 | |
| 825 | 798 | fn transCStyleCastExprClass( |
| ... | ... | @@ -828,7 +801,7 @@ fn transCStyleCastExprClass( |
| 828 | 801 | stmt: *const ZigClangCStyleCastExpr, |
| 829 | 802 | result_used: ResultUsed, |
| 830 | 803 | lrvalue: LRValue, |
| 831 | | ) !TransResult { |
| 804 | ) TransError!*ast.Node { |
| 832 | 805 | const sub_expr = ZigClangCStyleCastExpr_getSubExpr(stmt); |
| 833 | 806 | const cast_node = (try transCCast( |
| 834 | 807 | rp, |
| ... | ... | @@ -836,20 +809,14 @@ fn transCStyleCastExprClass( |
| 836 | 809 | ZigClangCStyleCastExpr_getBeginLoc(stmt), |
| 837 | 810 | ZigClangCStyleCastExpr_getType(stmt), |
| 838 | 811 | ZigClangExpr_getType(sub_expr), |
| 839 | | (try transExpr(rp, scope, sub_expr, .used, lrvalue)).node, |
| 812 | try transExpr(rp, scope, sub_expr, .used, lrvalue), |
| 840 | 813 | )); |
| 841 | | const cast_res = TransResult{ |
| 842 | | .node = cast_node, |
| 843 | | .child_scope = scope, |
| 844 | | .node_scope = scope, |
| 845 | | }; |
| 846 | | return maybeSuppressResult(rp, scope, result_used, cast_res); |
| 814 | return maybeSuppressResult(rp, scope, result_used, cast_node); |
| 847 | 815 | } |
| 848 | 816 | |
| 849 | | fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDeclStmt) TransError!TransResult { |
| 817 | fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) TransError!*ast.Node { |
| 850 | 818 | const c = rp.c; |
| 851 | | const block_scope = parent_scope.findBlockScope(); |
| 852 | | var scope = parent_scope; |
| 819 | const block_scope = scope.findBlockScope(); |
| 853 | 820 | |
| 854 | 821 | var it = ZigClangDeclStmt_decl_begin(stmt); |
| 855 | 822 | const end_it = ZigClangDeclStmt_decl_end(stmt); |
| ... | ... | @@ -867,18 +834,14 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe |
| 867 | 834 | try appendToken(c, .Keyword_const, "const") |
| 868 | 835 | else |
| 869 | 836 | try appendToken(c, .Keyword_var, "var"); |
| 870 | | const c_name = try c.str(ZigClangDecl_getName_bytes_begin( |
| 837 | const name = try c.str(ZigClangDecl_getName_bytes_begin( |
| 871 | 838 | @ptrCast(*const ZigClangDecl, var_decl), |
| 872 | 839 | )); |
| 873 | | const name_token = try appendIdentifier(c, c_name, null); // TODO parent_scope); |
| 874 | | |
| 875 | | const var_scope = try c.a().create(Scope.Var); |
| 876 | | var_scope.* = Scope.Var{ |
| 877 | | .base = Scope{ .id = .Var, .parent = scope }, |
| 878 | | .c_name = c_name, |
| 879 | | .zig_name = c_name, // TODO: getWantedName |
| 880 | | }; |
| 881 | | scope = &var_scope.base; |
| 840 | const checked_name = if (try scope.createAlias(c, name)) |a| blk: { |
| 841 | try block_scope.variables.push(.{ .name = name, .alias = a }); |
| 842 | break :blk a; |
| 843 | } else name; |
| 844 | const name_token = try appendIdentifier(c, checked_name); |
| 882 | 845 | |
| 883 | 846 | const colon_token = try appendToken(c, .Colon, ":"); |
| 884 | 847 | const loc = ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)); |
| ... | ... | @@ -886,7 +849,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe |
| 886 | 849 | |
| 887 | 850 | const eq_token = try appendToken(c, .Equal, "="); |
| 888 | 851 | const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| |
| 889 | | (try transExpr(rp, scope, expr, .used, .r_value)).node |
| 852 | try transExpr(rp, scope, expr, .used, .r_value) |
| 890 | 853 | else |
| 891 | 854 | try transCreateNodeUndefinedLiteral(c); |
| 892 | 855 | const semicolon_token = try appendToken(c, .Semicolon, ";"); |
| ... | ... | @@ -910,7 +873,6 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe |
| 910 | 873 | }; |
| 911 | 874 | try block_scope.block_node.statements.push(&node.base); |
| 912 | 875 | }, |
| 913 | | |
| 914 | 876 | else => |kind| return revertAndWarn( |
| 915 | 877 | rp, |
| 916 | 878 | error.UnsupportedTranslation, |
| ... | ... | @@ -920,12 +882,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe |
| 920 | 882 | ), |
| 921 | 883 | } |
| 922 | 884 | } |
| 923 | | |
| 924 | | return TransResult{ |
| 925 | | .node = &block_scope.block_node.base, |
| 926 | | .node_scope = scope, |
| 927 | | .child_scope = scope, |
| 928 | | }; |
| 885 | return &block_scope.block_node.base; |
| 929 | 886 | } |
| 930 | 887 | |
| 931 | 888 | fn transDeclRefExpr( |
| ... | ... | @@ -933,17 +890,12 @@ fn transDeclRefExpr( |
| 933 | 890 | scope: *Scope, |
| 934 | 891 | expr: *const ZigClangDeclRefExpr, |
| 935 | 892 | lrvalue: LRValue, |
| 936 | | ) !TransResult { |
| 893 | ) TransError!*ast.Node { |
| 937 | 894 | const value_decl = ZigClangDeclRefExpr_getDecl(expr); |
| 938 | | const c_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl))); |
| 939 | | const zig_name = transLookupZigIdentifier(scope, c_name); |
| 940 | | if (lrvalue == .l_value) try rp.c.ptr_params.put(zig_name); |
| 941 | | const node = try transCreateNodeIdentifier(rp.c, zig_name, null); // TODO scope); |
| 942 | | return TransResult{ |
| 943 | | .node = node, |
| 944 | | .node_scope = scope, |
| 945 | | .child_scope = scope, |
| 946 | | }; |
| 895 | const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl))); |
| 896 | const checked_name = if (scope.getAlias(name)) |a| a else name; |
| 897 | if (lrvalue == .l_value) try rp.c.ptr_params.put(checked_name); |
| 898 | return transCreateNodeIdentifier(rp.c, checked_name); |
| 947 | 899 | } |
| 948 | 900 | |
| 949 | 901 | fn transImplicitCastExpr( |
| ... | ... | @@ -951,7 +903,7 @@ fn transImplicitCastExpr( |
| 951 | 903 | scope: *Scope, |
| 952 | 904 | expr: *const ZigClangImplicitCastExpr, |
| 953 | 905 | result_used: ResultUsed, |
| 954 | | ) !TransResult { |
| 906 | ) TransError!*ast.Node { |
| 955 | 907 | const c = rp.c; |
| 956 | 908 | const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr); |
| 957 | 909 | const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value); |
| ... | ... | @@ -959,20 +911,12 @@ fn transImplicitCastExpr( |
| 959 | 911 | .BitCast => { |
| 960 | 912 | const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); |
| 961 | 913 | const src_type = getExprQualType(c, sub_expr); |
| 962 | | return TransResult{ |
| 963 | | .node = try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node.node), |
| 964 | | .node_scope = scope, |
| 965 | | .child_scope = scope, |
| 966 | | }; |
| 914 | return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node); |
| 967 | 915 | }, |
| 968 | 916 | .IntegralCast => { |
| 969 | 917 | const dest_type = ZigClangExpr_getType(@ptrCast(*const ZigClangExpr, expr)); |
| 970 | 918 | const src_type = ZigClangExpr_getType(sub_expr); |
| 971 | | return TransResult{ |
| 972 | | .node = try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node.node), |
| 973 | | .node_scope = scope, |
| 974 | | .child_scope = scope, |
| 975 | | }; |
| 919 | return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node); |
| 976 | 920 | }, |
| 977 | 921 | .FunctionToPointerDecay, .ArrayToPointerDecay => { |
| 978 | 922 | return maybeSuppressResult(rp, scope, result_used, sub_expr_node); |
| ... | ... | @@ -981,11 +925,7 @@ fn transImplicitCastExpr( |
| 981 | 925 | return transExpr(rp, scope, sub_expr, .used, .r_value); |
| 982 | 926 | }, |
| 983 | 927 | .NullToPointer => { |
| 984 | | return TransResult{ |
| 985 | | .node = try transCreateNodeNullLiteral(rp.c), |
| 986 | | .node_scope = scope, |
| 987 | | .child_scope = scope, |
| 988 | | }; |
| 928 | return transCreateNodeNullLiteral(rp.c); |
| 989 | 929 | }, |
| 990 | 930 | else => |kind| return revertAndWarn( |
| 991 | 931 | rp, |
| ... | ... | @@ -1002,36 +942,27 @@ fn transIntegerLiteral( |
| 1002 | 942 | scope: *Scope, |
| 1003 | 943 | expr: *const ZigClangIntegerLiteral, |
| 1004 | 944 | result_used: ResultUsed, |
| 1005 | | ) !TransResult { |
| 945 | ) TransError!*ast.Node { |
| 1006 | 946 | var eval_result: ZigClangExprEvalResult = undefined; |
| 1007 | 947 | if (!ZigClangIntegerLiteral_EvaluateAsInt(expr, &eval_result, rp.c.clang_context)) { |
| 1008 | 948 | const loc = ZigClangIntegerLiteral_getBeginLoc(expr); |
| 1009 | 949 | return revertAndWarn(rp, error.UnsupportedTranslation, loc, "invalid integer literal", .{}); |
| 1010 | 950 | } |
| 1011 | 951 | const node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val)); |
| 1012 | | const res = TransResult{ |
| 1013 | | .node = node, |
| 1014 | | .child_scope = scope, |
| 1015 | | .node_scope = scope, |
| 1016 | | }; |
| 1017 | | return maybeSuppressResult(rp, scope, result_used, res); |
| 952 | return maybeSuppressResult(rp, scope, result_used, node); |
| 1018 | 953 | } |
| 1019 | 954 | |
| 1020 | 955 | fn transReturnStmt( |
| 1021 | 956 | rp: RestorePoint, |
| 1022 | 957 | scope: *Scope, |
| 1023 | 958 | expr: *const ZigClangReturnStmt, |
| 1024 | | ) !TransResult { |
| 959 | ) TransError!*ast.Node { |
| 1025 | 960 | const node = try transCreateNodeReturnExpr(rp.c); |
| 1026 | 961 | if (ZigClangReturnStmt_getRetValue(expr)) |val_expr| { |
| 1027 | | node.rhs = (try transExpr(rp, scope, val_expr, .used, .r_value)).node; |
| 962 | node.rhs = try transExpr(rp, scope, val_expr, .used, .r_value); |
| 1028 | 963 | } |
| 1029 | 964 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 1030 | | return TransResult{ |
| 1031 | | .node = &node.base, |
| 1032 | | .child_scope = scope, |
| 1033 | | .node_scope = scope, |
| 1034 | | }; |
| 965 | return &node.base; |
| 1035 | 966 | } |
| 1036 | 967 | |
| 1037 | 968 | fn transStringLiteral( |
| ... | ... | @@ -1039,7 +970,7 @@ fn transStringLiteral( |
| 1039 | 970 | scope: *Scope, |
| 1040 | 971 | stmt: *const ZigClangStringLiteral, |
| 1041 | 972 | result_used: ResultUsed, |
| 1042 | | ) !TransResult { |
| 973 | ) TransError!*ast.Node { |
| 1043 | 974 | const kind = ZigClangStringLiteral_getKind(stmt); |
| 1044 | 975 | switch (kind) { |
| 1045 | 976 | .Ascii, .UTF8 => { |
| ... | ... | @@ -1061,12 +992,7 @@ fn transStringLiteral( |
| 1061 | 992 | node.* = ast.Node.StringLiteral{ |
| 1062 | 993 | .token = token, |
| 1063 | 994 | }; |
| 1064 | | const res = TransResult{ |
| 1065 | | .node = &node.base, |
| 1066 | | .child_scope = scope, |
| 1067 | | .node_scope = scope, |
| 1068 | | }; |
| 1069 | | return maybeSuppressResult(rp, scope, result_used, res); |
| 995 | return maybeSuppressResult(rp, scope, result_used, &node.base); |
| 1070 | 996 | }, |
| 1071 | 997 | .UTF16, .UTF32, .Wide => return revertAndWarn( |
| 1072 | 998 | rp, |
| ... | ... | @@ -1159,7 +1085,7 @@ fn transExpr( |
| 1159 | 1085 | expr: *const ZigClangExpr, |
| 1160 | 1086 | used: ResultUsed, |
| 1161 | 1087 | lrvalue: LRValue, |
| 1162 | | ) TransError!TransResult { |
| 1088 | ) TransError!*ast.Node { |
| 1163 | 1089 | return transStmt(rp, scope, @ptrCast(*const ZigClangStmt, expr), used, lrvalue); |
| 1164 | 1090 | } |
| 1165 | 1091 | |
| ... | ... | @@ -1168,7 +1094,7 @@ fn transInitListExpr( |
| 1168 | 1094 | scope: *Scope, |
| 1169 | 1095 | expr: *const ZigClangInitListExpr, |
| 1170 | 1096 | used: ResultUsed, |
| 1171 | | ) TransError!TransResult { |
| 1097 | ) TransError!*ast.Node { |
| 1172 | 1098 | const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr)); |
| 1173 | 1099 | const qual_type = ZigClangQualType_getTypePtr(qt); |
| 1174 | 1100 | const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr)); |
| ... | ... | @@ -1199,16 +1125,12 @@ fn transInitListExpr( |
| 1199 | 1125 | var i: c_uint = 0; |
| 1200 | 1126 | while (i < init_count) : (i += 1) { |
| 1201 | 1127 | const elem_expr = ZigClangInitListExpr_getInit(expr, i); |
| 1202 | | try init_node.op.ArrayInitializer.push((try transExpr(rp, scope, elem_expr, .used, .r_value)).node); |
| 1128 | try init_node.op.ArrayInitializer.push(try transExpr(rp, scope, elem_expr, .used, .r_value)); |
| 1203 | 1129 | _ = try appendToken(rp.c, .Comma, ","); |
| 1204 | 1130 | } |
| 1205 | 1131 | init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); |
| 1206 | 1132 | if (leftover_count == 0) { |
| 1207 | | return TransResult{ |
| 1208 | | .node = &init_node.base, |
| 1209 | | .child_scope = scope, |
| 1210 | | .node_scope = scope, |
| 1211 | | }; |
| 1133 | return &init_node.base; |
| 1212 | 1134 | } |
| 1213 | 1135 | cat_tok = try appendToken(rp.c, .PlusPlus, "++"); |
| 1214 | 1136 | } |
| ... | ... | @@ -1216,7 +1138,7 @@ fn transInitListExpr( |
| 1216 | 1138 | const dot_tok = try appendToken(rp.c, .Period, "."); |
| 1217 | 1139 | var filler_init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok); |
| 1218 | 1140 | const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr); |
| 1219 | | try filler_init_node.op.ArrayInitializer.push((try transExpr(rp, scope, filler_val_expr, .used, .r_value)).node); |
| 1141 | try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value)); |
| 1220 | 1142 | filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); |
| 1221 | 1143 | |
| 1222 | 1144 | const rhs_node = if (leftover_count == 1) |
| ... | ... | @@ -1234,11 +1156,7 @@ fn transInitListExpr( |
| 1234 | 1156 | }; |
| 1235 | 1157 | |
| 1236 | 1158 | if (init_count == 0) { |
| 1237 | | return TransResult{ |
| 1238 | | .node = rhs_node, |
| 1239 | | .child_scope = scope, |
| 1240 | | .node_scope = scope, |
| 1241 | | }; |
| 1159 | return rhs_node; |
| 1242 | 1160 | } |
| 1243 | 1161 | |
| 1244 | 1162 | const cat_node = try rp.c.a().create(ast.Node.InfixOp); |
| ... | ... | @@ -1248,11 +1166,7 @@ fn transInitListExpr( |
| 1248 | 1166 | .op = .ArrayCat, |
| 1249 | 1167 | .rhs = rhs_node, |
| 1250 | 1168 | }; |
| 1251 | | return TransResult{ |
| 1252 | | .node = &cat_node.base, |
| 1253 | | .child_scope = scope, |
| 1254 | | .node_scope = scope, |
| 1255 | | }; |
| 1169 | return &cat_node.base; |
| 1256 | 1170 | } |
| 1257 | 1171 | |
| 1258 | 1172 | fn transImplicitValueInitExpr( |
| ... | ... | @@ -1260,7 +1174,7 @@ fn transImplicitValueInitExpr( |
| 1260 | 1174 | scope: *Scope, |
| 1261 | 1175 | expr: *const ZigClangExpr, |
| 1262 | 1176 | used: ResultUsed, |
| 1263 | | ) TransError!TransResult { |
| 1177 | ) TransError!*ast.Node { |
| 1264 | 1178 | const source_loc = ZigClangExpr_getBeginLoc(expr); |
| 1265 | 1179 | const qt = getExprQualType(rp.c, expr); |
| 1266 | 1180 | const ty = ZigClangQualType_getTypePtr(qt); |
| ... | ... | @@ -1268,9 +1182,7 @@ fn transImplicitValueInitExpr( |
| 1268 | 1182 | .Builtin => blk: { |
| 1269 | 1183 | const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty); |
| 1270 | 1184 | switch (ZigClangBuiltinType_getKind(builtin_ty)) { |
| 1271 | | .Bool => { |
| 1272 | | break :blk try transCreateNodeBoolLiteral(rp.c, false); |
| 1273 | | }, |
| 1185 | .Bool => return transCreateNodeBoolLiteral(rp.c, false), |
| 1274 | 1186 | .Char_U, |
| 1275 | 1187 | .UChar, |
| 1276 | 1188 | .Char_S, |
| ... | ... | @@ -1291,30 +1203,13 @@ fn transImplicitValueInitExpr( |
| 1291 | 1203 | .Float128, |
| 1292 | 1204 | .Float16, |
| 1293 | 1205 | .LongDouble, |
| 1294 | | => { |
| 1295 | | break :blk try transCreateNodeInt(rp.c, 0); |
| 1296 | | }, |
| 1206 | => return transCreateNodeInt(rp.c, 0), |
| 1297 | 1207 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), |
| 1298 | 1208 | } |
| 1299 | 1209 | }, |
| 1300 | | .Pointer => try transCreateNodeNullLiteral(rp.c), |
| 1210 | .Pointer => return transCreateNodeNullLiteral(rp.c), |
| 1301 | 1211 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "type does not have an implicit init value", .{}), |
| 1302 | 1212 | }; |
| 1303 | | return TransResult{ |
| 1304 | | .node = node, |
| 1305 | | .child_scope = scope, |
| 1306 | | .node_scope = scope, |
| 1307 | | }; |
| 1308 | | } |
| 1309 | | |
| 1310 | | fn transLookupZigIdentifier(inner: *Scope, c_name: []const u8) []const u8 { |
| 1311 | | var scope = inner; |
| 1312 | | while (true) : (scope = scope.parent orelse return c_name) { |
| 1313 | | if (scope.id == .Var) { |
| 1314 | | const var_scope = @ptrCast(*const Scope.Var, scope); |
| 1315 | | if (std.mem.eql(u8, var_scope.c_name, c_name)) return var_scope.zig_name; |
| 1316 | | } |
| 1317 | | } |
| 1318 | 1213 | } |
| 1319 | 1214 | |
| 1320 | 1215 | fn transCPtrCast( |
| ... | ... | @@ -1358,25 +1253,21 @@ fn maybeSuppressResult( |
| 1358 | 1253 | rp: RestorePoint, |
| 1359 | 1254 | scope: *Scope, |
| 1360 | 1255 | used: ResultUsed, |
| 1361 | | result: TransResult, |
| 1362 | | ) !TransResult { |
| 1256 | result: *ast.Node, |
| 1257 | ) TransError!*ast.Node { |
| 1363 | 1258 | if (used == .used) return result; |
| 1364 | 1259 | // NOTE: This is backwards, but the semicolon must immediately follow the node. |
| 1365 | 1260 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 1366 | | const lhs = try transCreateNodeIdentifier(rp.c, "_", null); |
| 1261 | const lhs = try transCreateNodeIdentifier(rp.c, "_"); |
| 1367 | 1262 | const op_token = try appendToken(rp.c, .Equal, "="); |
| 1368 | 1263 | const op_node = try rp.c.a().create(ast.Node.InfixOp); |
| 1369 | 1264 | op_node.* = ast.Node.InfixOp{ |
| 1370 | 1265 | .op_token = op_token, |
| 1371 | 1266 | .lhs = lhs, |
| 1372 | 1267 | .op = .Assign, |
| 1373 | | .rhs = result.node, |
| 1374 | | }; |
| 1375 | | return TransResult{ |
| 1376 | | .node = &op_node.base, |
| 1377 | | .child_scope = scope, |
| 1378 | | .node_scope = scope, |
| 1268 | .rhs = result, |
| 1379 | 1269 | }; |
| 1270 | return &op_node.base; |
| 1380 | 1271 | } |
| 1381 | 1272 | |
| 1382 | 1273 | fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { |
| ... | ... | @@ -1443,7 +1334,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro |
| 1443 | 1334 | return node; |
| 1444 | 1335 | } |
| 1445 | 1336 | |
| 1446 | | const field_name = try appendIdentifier(c, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))), null); |
| 1337 | const field_name = try appendIdentifier(c, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl)))); |
| 1447 | 1338 | _ = try appendToken(c, .Colon, ":"); |
| 1448 | 1339 | const field_type = try transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc); |
| 1449 | 1340 | |
| ... | ... | @@ -1467,7 +1358,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro |
| 1467 | 1358 | |
| 1468 | 1359 | fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.Node { |
| 1469 | 1360 | if (c.decl_table.get(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)))) |name| |
| 1470 | | return try transCreateNodeIdentifier(c, name.value, null); // Avoid processing this decl twice |
| 1361 | return try transCreateNodeIdentifier(c, name.value); // Avoid processing this decl twice |
| 1471 | 1362 | const rp = makeRestorePoint(c); |
| 1472 | 1363 | const enum_loc = ZigClangEnumDecl_getLocation(enum_decl); |
| 1473 | 1364 | |
| ... | ... | @@ -1483,7 +1374,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1483 | 1374 | |
| 1484 | 1375 | const name = try std.fmt.allocPrint(c.a(), "enum_{}", .{bare_name}); |
| 1485 | 1376 | _ = try c.decl_table.put(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)), name); |
| 1486 | | const name_tok = try appendIdentifier(c, name, null); |
| 1377 | const name_tok = try appendIdentifier(c, name); |
| 1487 | 1378 | const eq_tok = try appendToken(c, .Equal, "="); |
| 1488 | 1379 | |
| 1489 | 1380 | const init_node = if (ZigClangEnumDecl_getDefinition(enum_decl)) |enum_def| blk: { |
| ... | ... | @@ -1550,7 +1441,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1550 | 1441 | else |
| 1551 | 1442 | enum_val_name; |
| 1552 | 1443 | |
| 1553 | | const field_name_tok = try appendIdentifier(c, field_name, null); |
| 1444 | const field_name_tok = try appendIdentifier(c, field_name); |
| 1554 | 1445 | |
| 1555 | 1446 | const int_node = if (!pure_enum) blk: { |
| 1556 | 1447 | _ = try appendToken(c, .Colon, "="); |
| ... | ... | @@ -1603,18 +1494,18 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1603 | 1494 | try addTopLevelDecl(c, name, &node.base); |
| 1604 | 1495 | if (!is_unnamed) |
| 1605 | 1496 | try c.alias_list.push(.{ .alias = bare_name, .name = name }); |
| 1606 | | return transCreateNodeIdentifier(c, name, null); |
| 1497 | return transCreateNodeIdentifier(c, name); |
| 1607 | 1498 | } |
| 1608 | 1499 | |
| 1609 | 1500 | fn addEnumTopLevel(c: *Context, enum_name: []const u8, field_name: []const u8, enum_val_name: []const u8) !void { |
| 1610 | 1501 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 1611 | 1502 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| 1612 | | const name_tok = try appendIdentifier(c, enum_val_name, null); |
| 1503 | const name_tok = try appendIdentifier(c, enum_val_name); |
| 1613 | 1504 | const eq_tok = try appendToken(c, .Equal, "="); |
| 1614 | 1505 | |
| 1615 | | const enum_ident = try transCreateNodeIdentifier(c, enum_name, null); |
| 1506 | const enum_ident = try transCreateNodeIdentifier(c, enum_name); |
| 1616 | 1507 | const period_tok = try appendToken(c, .Period, "."); |
| 1617 | | const field_ident = try transCreateNodeIdentifier(c, field_name, null); |
| 1508 | const field_ident = try transCreateNodeIdentifier(c, field_name); |
| 1618 | 1509 | |
| 1619 | 1510 | const field_access_node = try c.a().create(ast.Node.InfixOp); |
| 1620 | 1511 | field_access_node.* = .{ |
| ... | ... | @@ -1780,11 +1671,11 @@ fn transCreateNodeAssign( |
| 1780 | 1671 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 1781 | 1672 | |
| 1782 | 1673 | const node = try rp.c.a().create(ast.Node.InfixOp); |
| 1783 | | node.* = ast.Node.InfixOp{ |
| 1674 | node.* = .{ |
| 1784 | 1675 | .op_token = eq_token, |
| 1785 | | .lhs = lhs_node.node, |
| 1676 | .lhs = lhs_node, |
| 1786 | 1677 | .op = .Assign, |
| 1787 | | .rhs = rhs_node.node, |
| 1678 | .rhs = rhs_node, |
| 1788 | 1679 | }; |
| 1789 | 1680 | return node; |
| 1790 | 1681 | } |
| ... | ... | @@ -1864,9 +1755,9 @@ fn transCreateNodeInfixOp( |
| 1864 | 1755 | const node = try rp.c.a().create(ast.Node.InfixOp); |
| 1865 | 1756 | node.* = ast.Node.InfixOp{ |
| 1866 | 1757 | .op_token = op_token, |
| 1867 | | .lhs = lhs.node, |
| 1758 | .lhs = lhs, |
| 1868 | 1759 | .op = op, |
| 1869 | | .rhs = rhs.node, |
| 1760 | .rhs = rhs, |
| 1870 | 1761 | }; |
| 1871 | 1762 | if (!grouped) return &node.base; |
| 1872 | 1763 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| ... | ... | @@ -1896,7 +1787,7 @@ fn transCreateNodePtrType( |
| 1896 | 1787 | .Identifier => blk: { |
| 1897 | 1788 | const lbracket = try appendToken(c, .LBracket, "["); // Rendering checks if this token + 2 == .Identifier, so needs to return this token |
| 1898 | 1789 | _ = try appendToken(c, .Asterisk, "*"); |
| 1899 | | _ = try appendIdentifier(c, "c", null); // not really an identifier |
| 1790 | _ = try appendIdentifier(c, "c"); |
| 1900 | 1791 | _ = try appendToken(c, .RBracket, "]"); |
| 1901 | 1792 | break :blk lbracket; |
| 1902 | 1793 | }, |
| ... | ... | @@ -2019,7 +1910,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a |
| 2019 | 1910 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 2020 | 1911 | const inline_tok = try appendToken(c, .Keyword_inline, "inline"); |
| 2021 | 1912 | const fn_tok = try appendToken(c, .Keyword_fn, "fn"); |
| 2022 | | const name_tok = try appendIdentifier(c, name, null); |
| 1913 | const name_tok = try appendIdentifier(c, name); |
| 2023 | 1914 | _ = try appendToken(c, .LParen, "("); |
| 2024 | 1915 | |
| 2025 | 1916 | const proto_alias = proto_alias_node.cast(ast.Node.FnProto).?; |
| ... | ... | @@ -2068,7 +1959,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a |
| 2068 | 1959 | .section_expr = null, |
| 2069 | 1960 | }; |
| 2070 | 1961 | |
| 2071 | | const block = try transCreateNodeBlock(c, null, null); |
| 1962 | const block = try transCreateNodeBlock(c, null); |
| 2072 | 1963 | |
| 2073 | 1964 | const return_expr = try transCreateNodeReturnExpr(c); |
| 2074 | 1965 | const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?); |
| ... | ... | @@ -2079,7 +1970,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a |
| 2079 | 1970 | _ = try appendToken(c, .Comma, ","); |
| 2080 | 1971 | } |
| 2081 | 1972 | const param = pn.*.cast(ast.Node.ParamDecl).?; |
| 2082 | | try call_expr.op.Call.params.push(try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?), null)); |
| 1973 | try call_expr.op.Call.params.push(try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?))); |
| 2083 | 1974 | } |
| 2084 | 1975 | call_expr.rtoken = try appendToken(c, .RParen, ")"); |
| 2085 | 1976 | return_expr.rhs = &call_expr.base; |
| ... | ... | @@ -2107,7 +1998,7 @@ fn transCreateNodeEnumLiteral(c: *Context, name: []const u8) !*ast.Node { |
| 2107 | 1998 | const node = try c.a().create(ast.Node.EnumLiteral); |
| 2108 | 1999 | node.* = .{ |
| 2109 | 2000 | .dot = try appendToken(c, .Period, "."), |
| 2110 | | .name = try appendIdentifier(c, name, null), // scoped to an enum |
| 2001 | .name = try appendIdentifier(c, name), |
| 2111 | 2002 | }; |
| 2112 | 2003 | return &node.base; |
| 2113 | 2004 | } |
| ... | ... | @@ -2136,9 +2027,9 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else { |
| 2136 | 2027 | return node; |
| 2137 | 2028 | } |
| 2138 | 2029 | |
| 2139 | | fn transCreateNodeBlock(c: *Context, label: ?[]const u8, scope: ?*Scope) !*ast.Node.Block { |
| 2030 | fn transCreateNodeBlock(c: *Context, label: ?[]const u8) !*ast.Node.Block { |
| 2140 | 2031 | const label_node = if (label) |l| blk: { |
| 2141 | | const ll = try appendIdentifier(c, l, scope); |
| 2032 | const ll = try appendIdentifier(c, l); |
| 2142 | 2033 | _ = try appendToken(c, .Colon, ":"); |
| 2143 | 2034 | break :blk ll; |
| 2144 | 2035 | } else null; |
| ... | ... | @@ -2196,7 +2087,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 2196 | 2087 | .Float16 => "f16", |
| 2197 | 2088 | .LongDouble => "c_longdouble", |
| 2198 | 2089 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), |
| 2199 | | }, null); |
| 2090 | }); |
| 2200 | 2091 | }, |
| 2201 | 2092 | .FunctionProto => { |
| 2202 | 2093 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); |
| ... | ... | @@ -2274,7 +2165,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 2274 | 2165 | |
| 2275 | 2166 | const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); |
| 2276 | 2167 | const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl))); |
| 2277 | | return transCreateNodeIdentifier(rp.c, typedef_name, null); |
| 2168 | return transCreateNodeIdentifier(rp.c, typedef_name); |
| 2278 | 2169 | }, |
| 2279 | 2170 | .Record => { |
| 2280 | 2171 | const record_ty = @ptrCast(*const ZigClangRecordType, ty); |
| ... | ... | @@ -2288,7 +2179,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 2288 | 2179 | // }; |
| 2289 | 2180 | const record_decl = ZigClangRecordType_getDecl(record_ty); |
| 2290 | 2181 | if (try getContainerName(rp, record_decl)) |name| |
| 2291 | | return transCreateNodeIdentifier(rp.c, name, null) |
| 2182 | return transCreateNodeIdentifier(rp.c, name) |
| 2292 | 2183 | else |
| 2293 | 2184 | return transRecordDecl(rp.c, record_decl); |
| 2294 | 2185 | }, |
| ... | ... | @@ -2426,7 +2317,7 @@ fn finishTransFnProto( |
| 2426 | 2317 | else |
| 2427 | 2318 | null; |
| 2428 | 2319 | const fn_tok = try appendToken(rp.c, .Keyword_fn, "fn"); |
| 2429 | | const name_tok = if (fn_decl_context) |ctx| try appendIdentifier(rp.c, ctx.fn_name, null) else null; |
| 2320 | const name_tok = if (fn_decl_context) |ctx| try appendIdentifier(rp.c, ctx.fn_name) else null; |
| 2430 | 2321 | const lparen_tok = try appendToken(rp.c, .LParen, "("); |
| 2431 | 2322 | |
| 2432 | 2323 | var fn_params = ast.Node.FnProto.ParamList.init(rp.c.a()); |
| ... | ... | @@ -2449,7 +2340,7 @@ fn finishTransFnProto( |
| 2449 | 2340 | break :blk a; |
| 2450 | 2341 | } else param_name; |
| 2451 | 2342 | |
| 2452 | | const result = try appendIdentifier(rp.c, checked_param_name, null); |
| 2343 | const result = try appendIdentifier(rp.c, checked_param_name); |
| 2453 | 2344 | _ = try appendToken(rp.c, .Colon, ":"); |
| 2454 | 2345 | break :blk result; |
| 2455 | 2346 | } |
| ... | ... | @@ -2497,12 +2388,12 @@ fn finishTransFnProto( |
| 2497 | 2388 | |
| 2498 | 2389 | const return_type_node = blk: { |
| 2499 | 2390 | if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) { |
| 2500 | | break :blk try transCreateNodeIdentifier(rp.c, "noreturn", null); |
| 2391 | break :blk try transCreateNodeIdentifier(rp.c, "noreturn"); |
| 2501 | 2392 | } else { |
| 2502 | 2393 | const return_qt = ZigClangFunctionType_getReturnType(fn_ty); |
| 2503 | 2394 | if (isCVoid(return_qt)) { |
| 2504 | 2395 | // convert primitive c_void to actual void (only for return type) |
| 2505 | | break :blk try transCreateNodeIdentifier(rp.c, "void", null); |
| 2396 | break :blk try transCreateNodeIdentifier(rp.c, "void"); |
| 2506 | 2397 | } else { |
| 2507 | 2398 | break :blk transQualType(rp, return_qt, source_loc) catch |err| switch (err) { |
| 2508 | 2399 | error.UnsupportedType => { |
| ... | ... | @@ -2555,7 +2446,7 @@ fn emitWarning(c: *Context, loc: ZigClangSourceLocation, comptime format: []cons |
| 2555 | 2446 | fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime format: []const u8, args: var) !void { |
| 2556 | 2447 | // const name = @compileError(msg); |
| 2557 | 2448 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| 2558 | | const name_tok = try appendIdentifier(c, name, null); |
| 2449 | const name_tok = try appendIdentifier(c, name); |
| 2559 | 2450 | const eq_tok = try appendToken(c, .Equal, "="); |
| 2560 | 2451 | const builtin_tok = try appendToken(c, .Builtin, "@compileError"); |
| 2561 | 2452 | const lparen_tok = try appendToken(c, .LParen, "("); |
| ... | ... | @@ -2640,11 +2531,7 @@ fn isValidZigIdentifier(name: []const u8) bool { |
| 2640 | 2531 | return true; |
| 2641 | 2532 | } |
| 2642 | 2533 | |
| 2643 | | fn appendIdentifier(c: *Context, name: []const u8, scope: ?*Scope) !ast.TokenIndex { |
| 2644 | | if (scope) |s| |
| 2645 | | if (s.getAlias(name)) |alias| { |
| 2646 | | return appendTokenFmt(c, .Identifier, "{}", .{alias}); |
| 2647 | | }; |
| 2534 | fn appendIdentifier(c: *Context, name: []const u8) !ast.TokenIndex { |
| 2648 | 2535 | if (!isValidZigIdentifier(name) or std.zig.Token.getKeyword(name) != null) { |
| 2649 | 2536 | return appendTokenFmt(c, .Identifier, "@\"{}\"", .{name}); |
| 2650 | 2537 | } else { |
| ... | ... | @@ -2652,8 +2539,8 @@ fn appendIdentifier(c: *Context, name: []const u8, scope: ?*Scope) !ast.TokenInd |
| 2652 | 2539 | } |
| 2653 | 2540 | } |
| 2654 | 2541 | |
| 2655 | | fn transCreateNodeIdentifier(c: *Context, name: []const u8, scope: ?*Scope) !*ast.Node { |
| 2656 | | const token_index = try appendIdentifier(c, name, scope); |
| 2542 | fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node { |
| 2543 | const token_index = try appendIdentifier(c, name); |
| 2657 | 2544 | const identifier = try c.a().create(ast.Node.Identifier); |
| 2658 | 2545 | identifier.* = ast.Node.Identifier{ |
| 2659 | 2546 | .base = ast.Node{ .id = ast.Node.Id.Identifier }, |
| ... | ... | @@ -2740,7 +2627,7 @@ fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, |
| 2740 | 2627 | |
| 2741 | 2628 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 2742 | 2629 | const mut_tok = try appendToken(c, .Keyword_const, "const"); |
| 2743 | | const name_tok = try appendIdentifier(c, name, null); |
| 2630 | const name_tok = try appendIdentifier(c, name); |
| 2744 | 2631 | const eq_tok = try appendToken(c, .Equal, "="); |
| 2745 | 2632 | |
| 2746 | 2633 | const init_node = try parseCExpr(rp, it, source_loc, scope); |
| ... | ... | @@ -2773,7 +2660,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 2773 | 2660 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 2774 | 2661 | const inline_tok = try appendToken(c, .Keyword_inline, "inline"); |
| 2775 | 2662 | const fn_tok = try appendToken(c, .Keyword_fn, "fn"); |
| 2776 | | const name_tok = try appendIdentifier(c, name, null); |
| 2663 | const name_tok = try appendIdentifier(c, name); |
| 2777 | 2664 | _ = try appendToken(c, .LParen, "("); |
| 2778 | 2665 | |
| 2779 | 2666 | if (it.next().?.id != .LParen) { |
| ... | ... | @@ -2790,7 +2677,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 2790 | 2677 | break :blk alias; |
| 2791 | 2678 | } else param_tok.bytes; |
| 2792 | 2679 | |
| 2793 | | const param_name_tok = try appendIdentifier(c, checked_name, null); |
| 2680 | const param_name_tok = try appendIdentifier(c, checked_name); |
| 2794 | 2681 | _ = try appendToken(c, .Colon, ":"); |
| 2795 | 2682 | |
| 2796 | 2683 | const token_index = try appendToken(c, .Keyword_var, "var"); |
| ... | ... | @@ -2843,7 +2730,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 2843 | 2730 | .section_expr = null, |
| 2844 | 2731 | }; |
| 2845 | 2732 | |
| 2846 | | const block = try transCreateNodeBlock(c, null, null); |
| 2733 | const block = try transCreateNodeBlock(c, null); |
| 2847 | 2734 | |
| 2848 | 2735 | const return_expr = try transCreateNodeReturnExpr(c); |
| 2849 | 2736 | const expr = try parseCExpr(rp, it, source_loc, scope); |
| ... | ... | @@ -2888,7 +2775,7 @@ fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocati |
| 2888 | 2775 | .LL => "c_longlong", |
| 2889 | 2776 | .LLU => "c_ulonglong", |
| 2890 | 2777 | else => unreachable, |
| 2891 | | }, null)); |
| 2778 | })); |
| 2892 | 2779 | _ = try appendToken(rp.c, .Comma, ","); |
| 2893 | 2780 | try cast_node.params.push(try transCreateNodeInt(rp.c, tok.bytes)); |
| 2894 | 2781 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | ... | @@ -2902,7 +2789,7 @@ fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocati |
| 2902 | 2789 | .F => "f32", |
| 2903 | 2790 | .L => "f64", |
| 2904 | 2791 | else => unreachable, |
| 2905 | | }, null)); |
| 2792 | })); |
| 2906 | 2793 | _ = try appendToken(rp.c, .Comma, ","); |
| 2907 | 2794 | try cast_node.params.push(try transCreateNodeFloat(rp.c, tok.bytes)); |
| 2908 | 2795 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | ... | @@ -2939,7 +2826,10 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: |
| 2939 | 2826 | .NumLitInt, .NumLitFloat => { |
| 2940 | 2827 | return parseCNumLit(rp, tok, source_loc); |
| 2941 | 2828 | }, |
| 2942 | | .Identifier => return transCreateNodeIdentifier(rp.c, tok.bytes, scope), |
| 2829 | .Identifier => { |
| 2830 | const name = if (scope.getAlias(tok.bytes)) |a| a else tok.bytes; |
| 2831 | return transCreateNodeIdentifier(rp.c, name); |
| 2832 | }, |
| 2943 | 2833 | .LParen => { |
| 2944 | 2834 | const inner_node = try parseCExpr(rp, it, source_loc, scope); |
| 2945 | 2835 | |
| ... | ... | @@ -3060,7 +2950,7 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 3060 | 2950 | ); |
| 3061 | 2951 | |
| 3062 | 2952 | const op_token = try appendToken(rp.c, .Period, "."); |
| 3063 | | const rhs = try transCreateNodeIdentifier(rp.c, name_tok.bytes, null); // TODO scope); |
| 2953 | const rhs = try transCreateNodeIdentifier(rp.c, name_tok.bytes); |
| 3064 | 2954 | const access_node = try rp.c.a().create(ast.Node.InfixOp); |
| 3065 | 2955 | access_node.* = .{ |
| 3066 | 2956 | .op_token = op_token, |