| ... | ... | @@ -333,6 +333,7 @@ fn transStmt( |
| 333 | 333 | .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)), |
| 334 | 334 | .DeclRefExprClass => return transDeclRefExpr(rp, scope, @ptrCast(*const ZigClangDeclRefExpr, stmt), lrvalue), |
| 335 | 335 | .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt), result_used), |
| 336 | .IntegerLiteralClass => return transIntegerLiteral(rp, scope, @ptrCast(*const ZigClangIntegerLiteral, stmt), result_used), |
| 336 | 337 | else => { |
| 337 | 338 | return revertAndWarn( |
| 338 | 339 | rp, |
| ... | ... | @@ -534,6 +535,26 @@ fn transImplicitCastExpr( |
| 534 | 535 | } |
| 535 | 536 | } |
| 536 | 537 | |
| 538 | fn transIntegerLiteral( |
| 539 | rp: RestorePoint, |
| 540 | scope: *Scope, |
| 541 | expr: *const ZigClangIntegerLiteral, |
| 542 | result_used: ResultUsed, |
| 543 | ) !TransResult { |
| 544 | var eval_result: ZigClangExprEvalResult = undefined; |
| 545 | if (!ZigClangIntegerLiteral_EvaluateAsInt(expr, &eval_result, rp.c.clang_context)) { |
| 546 | const loc = ZigClangIntegerLiteral_getBeginLoc(expr); |
| 547 | return revertAndWarn(rp, error.UnsupportedTranslation, loc, "invalid integer literal"); |
| 548 | } |
| 549 | const node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val)); |
| 550 | const res = TransResult{ |
| 551 | .node = node, |
| 552 | .child_scope = scope, |
| 553 | .node_scope = scope, |
| 554 | }; |
| 555 | return maybeSuppressResult(rp, scope, result_used, res); |
| 556 | } |
| 557 | |
| 537 | 558 | fn transCCast( |
| 538 | 559 | rp: RestorePoint, |
| 539 | 560 | scope: *Scope, |
| ... | ... | @@ -547,14 +568,17 @@ fn transCCast( |
| 547 | 568 | if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type)) |
| 548 | 569 | return transCPtrCast(rp, loc, dst_type, src_type, expr); |
| 549 | 570 | if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) { |
| 550 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "ptrToInt"); |
| 571 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); |
| 551 | 572 | try builtin_node.params.push(expr); |
| 573 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 552 | 574 | return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), &builtin_node.base)).base; |
| 553 | 575 | } |
| 554 | 576 | if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) { |
| 555 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "intToPtr"); |
| 577 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); |
| 556 | 578 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| 579 | _ = try appendToken(rp.c, .Comma, ","); |
| 557 | 580 | try builtin_node.params.push(expr); |
| 581 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 558 | 582 | return &builtin_node.base; |
| 559 | 583 | } |
| 560 | 584 | // TODO: maybe widen to increase size |
| ... | ... | @@ -599,25 +623,28 @@ fn transCPtrCast( |
| 599 | 623 | ) !*ast.Node { |
| 600 | 624 | const ty = ZigClangQualType_getTypePtr(dst_type); |
| 601 | 625 | const child_type = ZigClangType_getPointeeType(ty); |
| 602 | | const dst_type_node = try transType(rp, ty, loc); |
| 603 | | const child_type_node = try transQualType(rp, child_type, loc); |
| 604 | 626 | |
| 605 | 627 | // Implicit downcasting from higher to lower alignment values is forbidden, |
| 606 | 628 | // use @alignCast to side-step this problem |
| 607 | | const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "ptrCast"); |
| 629 | const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast"); |
| 630 | const dst_type_node = try transType(rp, ty, loc); |
| 608 | 631 | try ptrcast_node.params.push(dst_type_node); |
| 632 | _ = try appendToken(rp.c, .Comma, ","); |
| 609 | 633 | |
| 610 | 634 | if (ZigClangType_isVoidType(qualTypeCanon(child_type))) { |
| 611 | 635 | // void has 1-byte alignment, so @alignCast is not needed |
| 612 | 636 | try ptrcast_node.params.push(expr); |
| 613 | 637 | } else { |
| 614 | | const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "alignOf"); |
| 638 | const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); |
| 639 | const child_type_node = try transQualType(rp, child_type, loc); |
| 615 | 640 | try alignof_node.params.push(child_type_node); |
| 616 | | const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "alignCast"); |
| 641 | const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); |
| 617 | 642 | try aligncast_node.params.push(&alignof_node.base); |
| 643 | _ = try appendToken(rp.c, .Comma, ","); |
| 618 | 644 | try aligncast_node.params.push(expr); |
| 619 | 645 | try ptrcast_node.params.push(&aligncast_node.base); |
| 620 | 646 | } |
| 647 | ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 621 | 648 | |
| 622 | 649 | return &ptrcast_node.base; |
| 623 | 650 | } |
| ... | ... | @@ -740,17 +767,20 @@ fn cIsUnsignedInteger(qt: ZigClangQualType) bool { |
| 740 | 767 | } |
| 741 | 768 | |
| 742 | 769 | fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall { |
| 770 | const builtin_token = try appendToken(c, .Builtin, name); |
| 771 | _ = try appendToken(c, .LParen, "("); |
| 743 | 772 | const node = try c.a().create(ast.Node.BuiltinCall); |
| 744 | 773 | node.* = ast.Node.BuiltinCall{ |
| 745 | 774 | .base = ast.Node{ .id = .BuiltinCall }, |
| 746 | | .builtin_token = try appendToken(c, .Builtin, name), |
| 775 | .builtin_token = builtin_token, |
| 747 | 776 | .params = ast.Node.BuiltinCall.ParamList.init(c.a()), |
| 748 | | .rparen_token = undefined, // TODO TokenIndex, |
| 777 | .rparen_token = undefined, // set after appending args |
| 749 | 778 | }; |
| 750 | 779 | return node; |
| 751 | 780 | } |
| 752 | 781 | |
| 753 | 782 | fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) !*ast.Node.SuffixOp { |
| 783 | _ = try appendToken(c, .LParen, "("); |
| 754 | 784 | const node = try c.a().create(ast.Node.SuffixOp); |
| 755 | 785 | node.* = ast.Node.SuffixOp{ |
| 756 | 786 | .base = ast.Node{ .id = .SuffixOp }, |
| ... | ... | @@ -761,16 +791,23 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) |
| 761 | 791 | .async_attr = null, |
| 762 | 792 | }, |
| 763 | 793 | }, |
| 764 | | .rtoken = undefined, // TODO TokenIndex |
| 794 | .rtoken = try appendToken(c, .RParen, ")"), |
| 765 | 795 | }; |
| 796 | try node.op.Call.params.push(first_arg); |
| 766 | 797 | return node; |
| 767 | 798 | } |
| 768 | 799 | |
| 769 | | fn transCreateNodePrefixOp(c: *Context, op: ast.Node.PrefixOp.Op, rhs: *ast.Node) !*ast.Node { |
| 800 | fn transCreateNodePrefixOp( |
| 801 | c: *Context, |
| 802 | op: ast.Node.PrefixOp.Op, |
| 803 | rhs: *ast.Node, |
| 804 | op_tok_id: std.zig.Token.Id, |
| 805 | bytes: []const u8, |
| 806 | ) !*ast.Node { |
| 770 | 807 | const node = try c.a().create(ast.Node.PrefixOp); |
| 771 | 808 | node.* = ast.Node.PrefixOp{ |
| 772 | 809 | .base = ast.Node{ .id = .PrefixOp }, |
| 773 | | .op_token = undefined, // TODO TokenIndex, |
| 810 | .op_token = try appendToken(c, op_tok_id, bytes), |
| 774 | 811 | .op = op, |
| 775 | 812 | .rhs = rhs, |
| 776 | 813 | }; |
| ... | ... | @@ -783,11 +820,12 @@ fn transCreateNodePtrType( |
| 783 | 820 | is_volatile: bool, |
| 784 | 821 | rhs: *ast.Node, |
| 785 | 822 | op_tok_id: std.zig.Token.Id, |
| 823 | bytes: []const u8, |
| 786 | 824 | ) !*ast.Node { |
| 787 | 825 | const node = try c.a().create(ast.Node.PrefixOp); |
| 788 | 826 | node.* = ast.Node.PrefixOp{ |
| 789 | 827 | .base = ast.Node{ .id = .PrefixOp }, |
| 790 | | .op_token = try appendToken(c, op_tok_id, ""), // TODO TokenIndex, |
| 828 | .op_token = try appendToken(c, op_tok_id, bytes), |
| 791 | 829 | .op = ast.Node.PrefixOp.Op{ |
| 792 | 830 | .PtrType = ast.Node.PrefixOp.PtrInfo{ |
| 793 | 831 | .allowzero_token = null, |
| ... | ... | @@ -801,6 +839,15 @@ fn transCreateNodePtrType( |
| 801 | 839 | return &node.base; |
| 802 | 840 | } |
| 803 | 841 | |
| 842 | fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { |
| 843 | const node = try c.a().create(ast.Node.IntegerLiteral); |
| 844 | node.* = ast.Node.IntegerLiteral{ |
| 845 | .base = ast.Node{ .id = .IntegerLiteral }, |
| 846 | .token = try appendToken(c, .IntegerLiteral, "3333333"), // TODO |
| 847 | }; |
| 848 | return &node.base; |
| 849 | } |
| 850 | |
| 804 | 851 | const RestorePoint = struct { |
| 805 | 852 | c: *Context, |
| 806 | 853 | token_index: ast.TokenIndex, |
| ... | ... | @@ -860,7 +907,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 860 | 907 | const child_qt = ZigClangType_getPointeeType(ty); |
| 861 | 908 | const child_node = try transQualType(rp, child_qt, source_loc); |
| 862 | 909 | if (qualTypeChildIsFnProto(child_qt)) |
| 863 | | return transCreateNodePrefixOp(rp.c, .OptionalType, child_node); |
| 910 | return transCreateNodePrefixOp(rp.c, .OptionalType, child_node, .QuestionMark, "?"); |
| 864 | 911 | if (typeIsOpaque(rp.c, ZigClangQualType_getTypePtr(child_qt), source_loc)) { |
| 865 | 912 | const pointer_node = try transCreateNodePtrType( |
| 866 | 913 | rp.c, |
| ... | ... | @@ -868,8 +915,9 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 868 | 915 | ZigClangQualType_isVolatileQualified(child_qt), |
| 869 | 916 | child_node, |
| 870 | 917 | .Asterisk, |
| 918 | "*", |
| 871 | 919 | ); |
| 872 | | return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node); |
| 920 | return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node, .QuestionMark, "?"); |
| 873 | 921 | } |
| 874 | 922 | return transCreateNodePtrType( |
| 875 | 923 | rp.c, |
| ... | ... | @@ -877,6 +925,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 877 | 925 | ZigClangQualType_isVolatileQualified(child_qt), |
| 878 | 926 | child_node, |
| 879 | 927 | .BracketStarCBracket, |
| 928 | "[*c]", |
| 880 | 929 | ); |
| 881 | 930 | }, |
| 882 | 931 | else => { |