| ... | @@ -184,9 +184,7 @@ const Scope = struct { | ... | @@ -184,9 +184,7 @@ const Scope = struct { |
| 184 | .Ref => null, | 184 | .Ref => null, |
| 185 | .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name), | 185 | .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name), |
| 186 | .Block => @fieldParentPtr(Block, "base", scope).getAlias(name), | 186 | .Block => @fieldParentPtr(Block, "base", scope).getAlias(name), |
| 187 | .Switch, | 187 | .Switch, .Loop, .Condition => scope.parent.?.getAlias(name), |
| 188 | .Loop, | | |
| 189 | .Condition => scope.parent.?.getAlias(name), | | |
| 190 | }; | 188 | }; |
| 191 | } | 189 | } |
| 192 | | 190 | |
| ... | @@ -196,9 +194,7 @@ const Scope = struct { | ... | @@ -196,9 +194,7 @@ const Scope = struct { |
| 196 | .Root => @fieldParentPtr(Root, "base", scope).contains(name), | 194 | .Root => @fieldParentPtr(Root, "base", scope).contains(name), |
| 197 | .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name), | 195 | .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name), |
| 198 | .Block => @fieldParentPtr(Block, "base", scope).contains(name), | 196 | .Block => @fieldParentPtr(Block, "base", scope).contains(name), |
| 199 | .Switch, | 197 | .Switch, .Loop, .Condition => scope.parent.?.contains(name), |
| 200 | .Loop, | | |
| 201 | .Condition => scope.parent.?.contains(name), | | |
| 202 | }; | 198 | }; |
| 203 | } | 199 | } |
| 204 | | 200 | |
| ... | @@ -594,7 +590,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -594,7 +590,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 594 | const node = try transCreateNodeVarDecl(c, true, true, name); | 590 | const node = try transCreateNodeVarDecl(c, true, true, name); |
| 595 | | 591 | |
| 596 | node.eq_token = try appendToken(c, .Equal, "="); | 592 | node.eq_token = try appendToken(c, .Equal, "="); |
| 597 | | 593 | |
| 598 | var semicolon: ast.TokenIndex = undefined; | 594 | var semicolon: ast.TokenIndex = undefined; |
| 599 | node.init_node = blk: { | 595 | node.init_node = blk: { |
| 600 | const rp = makeRestorePoint(c); | 596 | const rp = makeRestorePoint(c); |
| ... | @@ -634,12 +630,12 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -634,12 +630,12 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 634 | const field_name = try appendIdentifier(c, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl)))); | 630 | const field_name = try appendIdentifier(c, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl)))); |
| 635 | _ = try appendToken(c, .Colon, ":"); | 631 | _ = try appendToken(c, .Colon, ":"); |
| 636 | const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) { | 632 | const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) { |
| 637 | error.UnsupportedType => { | 633 | error.UnsupportedType => { |
| 638 | try failDecl(c, record_loc, name, "unable to translate {} member type", .{container_kind_name}); | 634 | try failDecl(c, record_loc, name, "unable to translate {} member type", .{container_kind_name}); |
| 639 | return null; | 635 | return null; |
| 640 | }, | 636 | }, |
| 641 | else => |e| return e, | 637 | else => |e| return e, |
| 642 | }; | 638 | }; |
| 643 | | 639 | |
| 644 | const field_node = try c.a().create(ast.Node.ContainerField); | 640 | const field_node = try c.a().create(ast.Node.ContainerField); |
| 645 | field_node.* = .{ | 641 | field_node.* = .{ |
| ... | @@ -879,205 +875,166 @@ fn transBinaryOperator( | ... | @@ -879,205 +875,166 @@ fn transBinaryOperator( |
| 879 | ) TransError!*ast.Node { | 875 | ) TransError!*ast.Node { |
| 880 | const op = ZigClangBinaryOperator_getOpcode(stmt); | 876 | const op = ZigClangBinaryOperator_getOpcode(stmt); |
| 881 | const qt = ZigClangBinaryOperator_getType(stmt); | 877 | const qt = ZigClangBinaryOperator_getType(stmt); |
| | 878 | var op_token: ast.TokenIndex = undefined; |
| | 879 | var op_id: ast.Node.InfixOp.Op = undefined; |
| 882 | switch (op) { | 880 | switch (op) { |
| 883 | .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn( | 881 | .Assign => return transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt)), |
| 884 | rp, | 882 | .Comma => { |
| 885 | error.UnsupportedTranslation, | 883 | const block_scope = try scope.findBlockScope(rp.c); |
| 886 | ZigClangBinaryOperator_getBeginLoc(stmt), | 884 | const expr = block_scope.base.parent == scope; |
| 887 | "TODO: handle more C binary operators: {}", | 885 | const lparen = if (expr) blk: { |
| 888 | .{op}, | 886 | const l = try appendToken(rp.c, .LParen, "("); |
| 889 | ), | 887 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); |
| 890 | .Assign => return try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt)), | 888 | break :blk l; |
| 891 | .Add => { | 889 | } else undefined; |
| 892 | const node = if (cIsUnsignedInteger(qt)) | 890 | |
| 893 | try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%", true) | 891 | const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value); |
| 894 | else | 892 | try block_scope.block_node.statements.push(lhs); |
| 895 | try transCreateNodeInfixOp(rp, scope, stmt, .Add, .Plus, "+", true); | 893 | |
| 896 | return maybeSuppressResult(rp, scope, result_used, node); | 894 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 897 | }, | 895 | if (expr) { |
| 898 | .Sub => { | 896 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 899 | const node = if (cIsUnsignedInteger(qt)) | 897 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 900 | try transCreateNodeInfixOp(rp, scope, stmt, .SubWrap, .MinusPercent, "-%", true) | 898 | break_node.rhs = rhs; |
| 901 | else | 899 | try block_scope.block_node.statements.push(&break_node.base); |
| 902 | try transCreateNodeInfixOp(rp, scope, stmt, .Sub, .Minus, "-", true); | 900 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 903 | return maybeSuppressResult(rp, scope, result_used, node); | 901 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| 904 | }, | 902 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); |
| 905 | .Mul => { | 903 | grouped_expr.* = .{ |
| 906 | const node = if (cIsUnsignedInteger(qt)) | 904 | .lparen = lparen, |
| 907 | try transCreateNodeInfixOp(rp, scope, stmt, .MultWrap, .AsteriskPercent, "*%", true) | 905 | .expr = &block_scope.block_node.base, |
| 908 | else | 906 | .rparen = rparen, |
| 909 | try transCreateNodeInfixOp(rp, scope, stmt, .Mult, .Asterisk, "*", true); | 907 | }; |
| 910 | return maybeSuppressResult(rp, scope, result_used, node); | 908 | return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base); |
| | 909 | } else { |
| | 910 | return maybeSuppressResult(rp, scope, result_used, rhs); |
| | 911 | } |
| 911 | }, | 912 | }, |
| 912 | .Div => { | 913 | .Div => { |
| 913 | if (!cIsUnsignedInteger(qt)) { | 914 | if (!cIsUnsignedInteger(qt)) { |
| 914 | // signed integer division uses @divTrunc | 915 | // signed integer division uses @divTrunc |
| 915 | const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc"); | 916 | const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc"); |
| 916 | const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); | 917 | try div_trunc_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value)); |
| 917 | try div_trunc_node.params.push(lhs); | | |
| 918 | _ = try appendToken(rp.c, .Comma, ","); | 918 | _ = try appendToken(rp.c, .Comma, ","); |
| 919 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | 919 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 920 | try div_trunc_node.params.push(rhs); | 920 | try div_trunc_node.params.push(rhs); |
| 921 | div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 921 | div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 922 | return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base); | 922 | return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base); |
| 923 | } else { | | |
| 924 | // unsigned/float division uses the operator | | |
| 925 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .Div, .Slash, "/", true); | | |
| 926 | return maybeSuppressResult(rp, scope, result_used, node); | | |
| 927 | } | 923 | } |
| 928 | }, | 924 | }, |
| 929 | .Rem => { | 925 | .Rem => { |
| 930 | if (!cIsUnsignedInteger(qt)) { | 926 | if (!cIsUnsignedInteger(qt)) { |
| 931 | // signed integer division uses @rem | 927 | // signed integer division uses @rem |
| 932 | const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem"); | 928 | const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem"); |
| 933 | const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); | 929 | try rem_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value)); |
| 934 | try rem_node.params.push(lhs); | | |
| 935 | _ = try appendToken(rp.c, .Comma, ","); | 930 | _ = try appendToken(rp.c, .Comma, ","); |
| 936 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | 931 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 937 | try rem_node.params.push(rhs); | 932 | try rem_node.params.push(rhs); |
| 938 | rem_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 933 | rem_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 939 | return maybeSuppressResult(rp, scope, result_used, &rem_node.base); | 934 | return maybeSuppressResult(rp, scope, result_used, &rem_node.base); |
| 940 | } else { | | |
| 941 | // unsigned/float division uses the operator | | |
| 942 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .Mod, .Percent, "%", true); | | |
| 943 | return maybeSuppressResult(rp, scope, result_used, node); | | |
| 944 | } | 935 | } |
| 945 | }, | 936 | }, |
| 946 | .Shl => { | 937 | .Shl => { |
| 947 | const node = try transCreateNodeShiftOp(rp, scope, stmt, .BitShiftLeft, .AngleBracketAngleBracketLeft, "<<"); | 938 | const node = try transCreateNodeShiftOp(rp, scope, stmt, .BitShiftLeft, .AngleBracketAngleBracketLeft, "<<"); |
| 948 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 939 | return maybeSuppressResult(rp, scope, result_used, node); |
| 949 | .node = node, | | |
| 950 | .child_scope = scope, | | |
| 951 | .node_scope = scope, | | |
| 952 | }); | | |
| 953 | }, | 940 | }, |
| 954 | .Shr => { | 941 | .Shr => { |
| 955 | const node = try transCreateNodeShiftOp(rp, scope, stmt, .BitShiftRight, .AngleBracketAngleBracketRight, ">>"); | 942 | const node = try transCreateNodeShiftOp(rp, scope, stmt, .BitShiftRight, .AngleBracketAngleBracketRight, ">>"); |
| 956 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 943 | return maybeSuppressResult(rp, scope, result_used, node); |
| 957 | .node = node, | 944 | }, |
| 958 | .child_scope = scope, | 945 | .LAnd => { |
| 959 | .node_scope = scope, | 946 | const node = try transCreateNodeBoolInfixOp(rp, scope, stmt, .BoolAnd, result_used, true); |
| 960 | }); | 947 | return maybeSuppressResult(rp, scope, result_used, node); |
| | 948 | }, |
| | 949 | .LOr => { |
| | 950 | const node = try transCreateNodeBoolInfixOp(rp, scope, stmt, .BoolOr, result_used, true); |
| | 951 | return maybeSuppressResult(rp, scope, result_used, node); |
| | 952 | }, |
| | 953 | else => {}, |
| | 954 | } |
| | 955 | const lhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); |
| | 956 | switch (op) { |
| | 957 | .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn( |
| | 958 | rp, |
| | 959 | error.UnsupportedTranslation, |
| | 960 | ZigClangBinaryOperator_getBeginLoc(stmt), |
| | 961 | "TODO: handle more C binary operators: {}", |
| | 962 | .{op}, |
| | 963 | ), |
| | 964 | .Add => { |
| | 965 | if (cIsUnsignedInteger(qt)) { |
| | 966 | op_token = try appendToken(rp.c, .PlusPercent, "+%"); |
| | 967 | op_id = .AddWrap; |
| | 968 | } else { |
| | 969 | op_token = try appendToken(rp.c, .Plus, "+"); |
| | 970 | op_id = .Add; |
| | 971 | } |
| | 972 | }, |
| | 973 | .Sub => { |
| | 974 | if (cIsUnsignedInteger(qt)) { |
| | 975 | op_token = try appendToken(rp.c, .MinusPercent, "-%"); |
| | 976 | op_id = .SubWrap; |
| | 977 | } else { |
| | 978 | op_token = try appendToken(rp.c, .Minus, "-"); |
| | 979 | op_id = .Sub; |
| | 980 | } |
| | 981 | }, |
| | 982 | .Mul => { |
| | 983 | if (cIsUnsignedInteger(qt)) { |
| | 984 | op_token = try appendToken(rp.c, .AsteriskPercent, "*%"); |
| | 985 | op_id = .MultWrap; |
| | 986 | } else { |
| | 987 | op_token = try appendToken(rp.c, .Asterisk, "*"); |
| | 988 | op_id = .Mult; |
| | 989 | } |
| | 990 | }, |
| | 991 | .Div => { |
| | 992 | // unsigned/float division uses the operator |
| | 993 | op_id = .Div; |
| | 994 | op_token = try appendToken(rp.c, .Slash, "/"); |
| | 995 | }, |
| | 996 | .Rem => { |
| | 997 | // unsigned/float division uses the operator |
| | 998 | op_id = .Mod; |
| | 999 | op_token = try appendToken(rp.c, .Percent, "%"); |
| 961 | }, | 1000 | }, |
| 962 | .LT => { | 1001 | .LT => { |
| 963 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .LessThan, .AngleBracketLeft, "<", true); | 1002 | op_id = .LessThan; |
| 964 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1003 | op_token = try appendToken(rp.c, .AngleBracketLeft, "<"); |
| 965 | .node = node, | | |
| 966 | .child_scope = scope, | | |
| 967 | .node_scope = scope, | | |
| 968 | }); | | |
| 969 | }, | 1004 | }, |
| 970 | .GT => { | 1005 | .GT => { |
| 971 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .GreaterThan, .AngleBracketRight, ">", true); | 1006 | op_id = .GreaterThan; |
| 972 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1007 | op_token = try appendToken(rp.c, .AngleBracketRight, ">"); |
| 973 | .node = node, | | |
| 974 | .child_scope = scope, | | |
| 975 | .node_scope = scope, | | |
| 976 | }); | | |
| 977 | }, | 1008 | }, |
| 978 | .LE => { | 1009 | .LE => { |
| 979 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .LessOrEqual, .AngleBracketLeftEqual, "<=", true); | 1010 | op_id = .LessOrEqual; |
| 980 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1011 | op_token = try appendToken(rp.c, .AngleBracketLeftEqual, "<="); |
| 981 | .node = node, | | |
| 982 | .child_scope = scope, | | |
| 983 | .node_scope = scope, | | |
| 984 | }); | | |
| 985 | }, | 1012 | }, |
| 986 | .GE => { | 1013 | .GE => { |
| 987 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .GreaterOrEqual, .AngleBracketRightEqual, ">=", true); | 1014 | op_id = .GreaterOrEqual; |
| 988 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1015 | op_token = try appendToken(rp.c, .AngleBracketRightEqual, ">="); |
| 989 | .node = node, | | |
| 990 | .child_scope = scope, | | |
| 991 | .node_scope = scope, | | |
| 992 | }); | | |
| 993 | }, | 1016 | }, |
| 994 | .EQ => { | 1017 | .EQ => { |
| 995 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .EqualEqual, .EqualEqual, "==", true); | 1018 | op_id = .EqualEqual; |
| 996 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1019 | op_token = try appendToken(rp.c, .EqualEqual, "=="); |
| 997 | .node = node, | | |
| 998 | .child_scope = scope, | | |
| 999 | .node_scope = scope, | | |
| 1000 | }); | | |
| 1001 | }, | 1020 | }, |
| 1002 | .NE => { | 1021 | .NE => { |
| 1003 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .BangEqual, .BangEqual, "!=", true); | 1022 | op_id = .BangEqual; |
| 1004 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1023 | op_token = try appendToken(rp.c, .BangEqual, "!="); |
| 1005 | .node = node, | | |
| 1006 | .child_scope = scope, | | |
| 1007 | .node_scope = scope, | | |
| 1008 | }); | | |
| 1009 | }, | 1024 | }, |
| 1010 | .And => { | 1025 | .And => { |
| 1011 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitAnd, .Ampersand, "&", true); | 1026 | op_id = .BitAnd; |
| 1012 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1027 | op_token = try appendToken(rp.c, .Ampersand, "&"); |
| 1013 | .node = node, | | |
| 1014 | .child_scope = scope, | | |
| 1015 | .node_scope = scope, | | |
| 1016 | }); | | |
| 1017 | }, | 1028 | }, |
| 1018 | .Xor => { | 1029 | .Xor => { |
| 1019 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitXor, .Caret, "^", true); | 1030 | op_id = .BitXor; |
| 1020 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1031 | op_token = try appendToken(rp.c, .Caret, "^"); |
| 1021 | .node = node, | | |
| 1022 | .child_scope = scope, | | |
| 1023 | .node_scope = scope, | | |
| 1024 | }); | | |
| 1025 | }, | 1032 | }, |
| 1026 | .Or => { | 1033 | .Or => { |
| 1027 | const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitOr, .Pipe, "|", true); | 1034 | op_id = .BitOr; |
| 1028 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | 1035 | op_token = try appendToken(rp.c, .Pipe, "|"); |
| 1029 | .node = node, | | |
| 1030 | .child_scope = scope, | | |
| 1031 | .node_scope = scope, | | |
| 1032 | }); | | |
| 1033 | }, | | |
| 1034 | .LAnd => { | | |
| 1035 | const node = try transCreateNodeBoolInfixOp(rp, scope, stmt, .BoolAnd, .Keyword_and, "and"); | | |
| 1036 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | | |
| 1037 | .node = node, | | |
| 1038 | .child_scope = scope, | | |
| 1039 | .node_scope = scope, | | |
| 1040 | }); | | |
| 1041 | }, | | |
| 1042 | .LOr => { | | |
| 1043 | const node = try transCreateNodeBoolInfixOp(rp, scope, stmt, .BoolOr, .Keyword_or, "or"); | | |
| 1044 | return maybeSuppressResult(rp, scope, result_used, TransResult{ | | |
| 1045 | .node = node, | | |
| 1046 | .child_scope = scope, | | |
| 1047 | .node_scope = scope, | | |
| 1048 | }); | | |
| 1049 | }, | | |
| 1050 | .Comma => { | | |
| 1051 | const block_scope = try scope.findBlockScope(rp.c); | | |
| 1052 | const expr = block_scope.base.parent == scope; | | |
| 1053 | const lparen = if (expr) blk: { | | |
| 1054 | const l = try appendToken(rp.c, .LParen, "("); | | |
| 1055 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); | | |
| 1056 | break :blk l; | | |
| 1057 | } else undefined; | | |
| 1058 | | | |
| 1059 | const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value); | | |
| 1060 | try block_scope.block_node.statements.push(lhs); | | |
| 1061 | | | |
| 1062 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | | |
| 1063 | if (expr) { | | |
| 1064 | _ = try appendToken(rp.c, .Semicolon, ";"); | | |
| 1065 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | | |
| 1066 | break_node.rhs = rhs; | | |
| 1067 | try block_scope.block_node.statements.push(&break_node.base); | | |
| 1068 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | | |
| 1069 | const rparen = try appendToken(rp.c, .RParen, ")"); | | |
| 1070 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); | | |
| 1071 | grouped_expr.* = .{ | | |
| 1072 | .lparen = lparen, | | |
| 1073 | .expr = &block_scope.block_node.base, | | |
| 1074 | .rparen = rparen, | | |
| 1075 | }; | | |
| 1076 | return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base); | | |
| 1077 | } else { | | |
| 1078 | return maybeSuppressResult(rp, scope, result_used, rhs); | | |
| 1079 | } | | |
| 1080 | }, | 1036 | }, |
| | 1037 | .Assign, |
| 1081 | .MulAssign, | 1038 | .MulAssign, |
| 1082 | .DivAssign, | 1039 | .DivAssign, |
| 1083 | .RemAssign, | 1040 | .RemAssign, |
| ... | @@ -1091,6 +1048,9 @@ fn transBinaryOperator( | ... | @@ -1091,6 +1048,9 @@ fn transBinaryOperator( |
| 1091 | => unreachable, | 1048 | => unreachable, |
| 1092 | else => unreachable, | 1049 | else => unreachable, |
| 1093 | } | 1050 | } |
| | 1051 | |
| | 1052 | const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| | 1053 | return transCreateNodeInfixOp(rp, scope, lhs_node, op_id, op_token, rhs_node, result_used, true); |
| 1094 | } | 1054 | } |
| 1095 | | 1055 | |
| 1096 | fn transCompoundStmtInline( | 1056 | fn transCompoundStmtInline( |
| ... | @@ -1231,56 +1191,22 @@ fn transImplicitCastExpr( | ... | @@ -1231,56 +1191,22 @@ fn transImplicitCastExpr( |
| 1231 | } | 1191 | } |
| 1232 | } | 1192 | } |
| 1233 | | 1193 | |
| 1234 | fn toEnumZeroCmp( | | |
| 1235 | rp: RestorePoint, | | |
| 1236 | scope: *Scope, | | |
| 1237 | expr: *ast.Node, | | |
| 1238 | generate_enum_node: fn (RestorePoint, *const struct_ZigClangType, source_loc: ZigClangSourceLocation) TransError!*ast.Node, | | |
| 1239 | enum_ty: *const struct_ZigClangType, | | |
| 1240 | enum_source_loc: ZigClangSourceLocation, | | |
| 1241 | ) !*ast.Node { | | |
| 1242 | // expr != @bitCast(EnumType, @as(@TagType(EnumType), 0)) | | |
| 1243 | | | |
| 1244 | // @bitCast(Enum, | | |
| 1245 | const bitcast = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast"); | | |
| 1246 | const bitcast_enum_identifier = try generate_enum_node(rp, enum_ty, enum_source_loc); | | |
| 1247 | try bitcast.params.push(bitcast_enum_identifier); | | |
| 1248 | _ = try appendToken(rp.c, .Comma, ","); | | |
| 1249 | | | |
| 1250 | // @as( | | |
| 1251 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | | |
| 1252 | | | |
| 1253 | // @TagType(Enum), | | |
| 1254 | const tag_type = try transCreateNodeBuiltinFnCall(rp.c, "@TagType"); | | |
| 1255 | const tag_type_enum_identifier = try generate_enum_node(rp, enum_ty, enum_source_loc); | | |
| 1256 | try tag_type.params.push(tag_type_enum_identifier); | | |
| 1257 | tag_type.rparen_token = try appendToken(rp.c, .RParen, ")"); | | |
| 1258 | try cast_node.params.push(&tag_type.base); | | |
| 1259 | _ = try appendToken(rp.c, .Comma, ","); | | |
| 1260 | | | |
| 1261 | // 0) | | |
| 1262 | const zero = try transCreateNodeInt(rp.c, 0); | | |
| 1263 | try cast_node.params.push(zero); | | |
| 1264 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | | |
| 1265 | | | |
| 1266 | try bitcast.params.push(&cast_node.base); | | |
| 1267 | bitcast.rparen_token = try appendToken(rp.c, .RParen, ")"); | | |
| 1268 | | | |
| 1269 | // expr != @bitCast(EnumType, @as(@TagType(EnumType), 0)) | | |
| 1270 | return transCreateNodeNotEqual(rp, scope, expr, &bitcast.base); | | |
| 1271 | } | | |
| 1272 | | | |
| 1273 | fn transBoolExpr( | 1194 | fn transBoolExpr( |
| 1274 | rp: RestorePoint, | 1195 | rp: RestorePoint, |
| 1275 | scope: *Scope, | 1196 | scope: *Scope, |
| 1276 | expr: *const ZigClangExpr, | 1197 | expr: *const ZigClangExpr, |
| 1277 | used: ResultUsed, | 1198 | used: ResultUsed, |
| 1278 | lrvalue: LRValue, | 1199 | lrvalue: LRValue, |
| 1279 | ) !*ast.Node { | 1200 | grouped: bool, |
| | 1201 | ) TransError!*ast.Node { |
| | 1202 | const lparen = if (grouped) |
| | 1203 | try appendToken(rp.c, .LParen, "(") |
| | 1204 | else |
| | 1205 | undefined; |
| 1280 | var res = try transExpr(rp, scope, expr, used, lrvalue); | 1206 | var res = try transExpr(rp, scope, expr, used, lrvalue); |
| 1281 | | 1207 | |
| 1282 | switch (res.node.id) { | 1208 | switch (res.id) { |
| 1283 | .InfixOp => switch (@ptrCast(*const ast.Node.InfixOp, &res.node).op) { | 1209 | .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) { |
| 1284 | .BoolOr, | 1210 | .BoolOr, |
| 1285 | .BoolAnd, | 1211 | .BoolAnd, |
| 1286 | .EqualEqual, | 1212 | .EqualEqual, |
| ... | @@ -1289,24 +1215,34 @@ fn transBoolExpr( | ... | @@ -1289,24 +1215,34 @@ fn transBoolExpr( |
| 1289 | .GreaterThan, | 1215 | .GreaterThan, |
| 1290 | .LessOrEqual, | 1216 | .LessOrEqual, |
| 1291 | .GreaterOrEqual, | 1217 | .GreaterOrEqual, |
| 1292 | => return res.node, | 1218 | => return res, |
| 1293 | | 1219 | |
| 1294 | else => {}, | 1220 | else => {}, |
| 1295 | }, | 1221 | }, |
| 1296 | | 1222 | |
| 1297 | .PrefixOp => switch (@ptrCast(*const ast.Node.PrefixOp, &res.node).op) { | 1223 | .PrefixOp => switch (@fieldParentPtr(ast.Node.PrefixOp, "base", res).op) { |
| 1298 | .BoolNot => return res.node, | 1224 | .BoolNot => return res, |
| 1299 | | 1225 | |
| 1300 | else => {}, | 1226 | else => {}, |
| 1301 | }, | 1227 | }, |
| 1302 | | 1228 | |
| 1303 | .BoolLiteral => return res.node, | 1229 | .BoolLiteral => return res, |
| 1304 | | 1230 | |
| 1305 | else => {}, | 1231 | else => {}, |
| 1306 | } | 1232 | } |
| 1307 | | | |
| 1308 | const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr)); | 1233 | const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr)); |
| | 1234 | return finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used, grouped); |
| | 1235 | } |
| 1309 | | 1236 | |
| | 1237 | fn finishBoolExpr( |
| | 1238 | rp: RestorePoint, |
| | 1239 | scope: *Scope, |
| | 1240 | loc: ZigClangSourceLocation, |
| | 1241 | ty: *const ZigClangType, |
| | 1242 | node: *ast.Node, |
| | 1243 | used: ResultUsed, |
| | 1244 | grouped: bool, |
| | 1245 | ) TransError!*ast.Node { |
| 1310 | switch (ZigClangType_getTypeClass(ty)) { | 1246 | switch (ZigClangType_getTypeClass(ty)) { |
| 1311 | .Builtin => { | 1247 | .Builtin => { |
| 1312 | const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty); | 1248 | const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty); |
| ... | @@ -1337,219 +1273,48 @@ fn transBoolExpr( | ... | @@ -1337,219 +1273,48 @@ fn transBoolExpr( |
| 1337 | .Char32, | 1273 | .Char32, |
| 1338 | .WChar_S, | 1274 | .WChar_S, |
| 1339 | .Float16, | 1275 | .Float16, |
| 1340 | => return transCreateNodeNotEqual(rp, scope, res.node, try transCreateNodeInt(rp.c, 0)), | 1276 | => { |
| 1341 | | 1277 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| 1342 | .NullPtr => return transCreateNodeNotEqual(rp, scope, res.node, try transCreateNodeNullLiteral(rp.c)), | 1278 | const rhs_node = try transCreateNodeInt(rp.c, 0); |
| 1343 | | 1279 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, grouped); |
| 1344 | .Void, | 1280 | }, |
| 1345 | .Half, | 1281 | .NullPtr => { |
| 1346 | .ObjCId, | 1282 | const op_token = try appendToken(rp.c, .EqualEqual, "=="); |
| 1347 | .ObjCClass, | 1283 | const rhs_node = try transCreateNodeNullLiteral(rp.c); |
| 1348 | .ObjCSel, | 1284 | return transCreateNodeInfixOp(rp, scope, node, .EqualEqual, op_token, rhs_node, used, grouped); |
| 1349 | .OMPArraySection, | 1285 | }, |
| 1350 | .Dependent, | | |
| 1351 | .Overload, | | |
| 1352 | .BoundMember, | | |
| 1353 | .PseudoObject, | | |
| 1354 | .UnknownAny, | | |
| 1355 | .BuiltinFn, | | |
| 1356 | .ARCUnbridgedCast, | | |
| 1357 | .OCLImage1dRO, | | |
| 1358 | .OCLImage1dArrayRO, | | |
| 1359 | .OCLImage1dBufferRO, | | |
| 1360 | .OCLImage2dRO, | | |
| 1361 | .OCLImage2dArrayRO, | | |
| 1362 | .OCLImage2dDepthRO, | | |
| 1363 | .OCLImage2dArrayDepthRO, | | |
| 1364 | .OCLImage2dMSAARO, | | |
| 1365 | .OCLImage2dArrayMSAARO, | | |
| 1366 | .OCLImage2dMSAADepthRO, | | |
| 1367 | .OCLImage2dArrayMSAADepthRO, | | |
| 1368 | .OCLImage3dRO, | | |
| 1369 | .OCLImage1dWO, | | |
| 1370 | .OCLImage1dArrayWO, | | |
| 1371 | .OCLImage1dBufferWO, | | |
| 1372 | .OCLImage2dWO, | | |
| 1373 | .OCLImage2dArrayWO, | | |
| 1374 | .OCLImage2dDepthWO, | | |
| 1375 | .OCLImage2dArrayDepthWO, | | |
| 1376 | .OCLImage2dMSAAWO, | | |
| 1377 | .OCLImage2dArrayMSAAWO, | | |
| 1378 | .OCLImage2dMSAADepthWO, | | |
| 1379 | .OCLImage2dArrayMSAADepthWO, | | |
| 1380 | .OCLImage3dWO, | | |
| 1381 | .OCLImage1dRW, | | |
| 1382 | .OCLImage1dArrayRW, | | |
| 1383 | .OCLImage1dBufferRW, | | |
| 1384 | .OCLImage2dRW, | | |
| 1385 | .OCLImage2dArrayRW, | | |
| 1386 | .OCLImage2dDepthRW, | | |
| 1387 | .OCLImage2dArrayDepthRW, | | |
| 1388 | .OCLImage2dMSAARW, | | |
| 1389 | .OCLImage2dArrayMSAARW, | | |
| 1390 | .OCLImage2dMSAADepthRW, | | |
| 1391 | .OCLImage2dArrayMSAADepthRW, | | |
| 1392 | .OCLImage3dRW, | | |
| 1393 | .OCLSampler, | | |
| 1394 | .OCLEvent, | | |
| 1395 | .OCLClkEvent, | | |
| 1396 | .OCLQueue, | | |
| 1397 | .OCLReserveID, | | |
| 1398 | .ShortAccum, | | |
| 1399 | .Accum, | | |
| 1400 | .LongAccum, | | |
| 1401 | .UShortAccum, | | |
| 1402 | .UAccum, | | |
| 1403 | .ULongAccum, | | |
| 1404 | .ShortFract, | | |
| 1405 | .Fract, | | |
| 1406 | .LongFract, | | |
| 1407 | .UShortFract, | | |
| 1408 | .UFract, | | |
| 1409 | .ULongFract, | | |
| 1410 | .SatShortAccum, | | |
| 1411 | .SatAccum, | | |
| 1412 | .SatLongAccum, | | |
| 1413 | .SatUShortAccum, | | |
| 1414 | .SatUAccum, | | |
| 1415 | .SatULongAccum, | | |
| 1416 | .SatShortFract, | | |
| 1417 | .SatFract, | | |
| 1418 | .SatLongFract, | | |
| 1419 | .SatUShortFract, | | |
| 1420 | .SatUFract, | | |
| 1421 | .SatULongFract, | | |
| 1422 | .OCLIntelSubgroupAVCMcePayload, | | |
| 1423 | .OCLIntelSubgroupAVCImePayload, | | |
| 1424 | .OCLIntelSubgroupAVCRefPayload, | | |
| 1425 | .OCLIntelSubgroupAVCSicPayload, | | |
| 1426 | .OCLIntelSubgroupAVCMceResult, | | |
| 1427 | .OCLIntelSubgroupAVCImeResult, | | |
| 1428 | .OCLIntelSubgroupAVCRefResult, | | |
| 1429 | .OCLIntelSubgroupAVCSicResult, | | |
| 1430 | .OCLIntelSubgroupAVCImeResultSingleRefStreamout, | | |
| 1431 | .OCLIntelSubgroupAVCImeResultDualRefStreamout, | | |
| 1432 | .OCLIntelSubgroupAVCImeSingleRefStreamin, | | |
| 1433 | .OCLIntelSubgroupAVCImeDualRefStreamin, | | |
| 1434 | => return res.node, | | |
| 1435 | | | |
| 1436 | else => {}, | 1286 | else => {}, |
| 1437 | } | 1287 | } |
| 1438 | }, | 1288 | }, |
| 1439 | .Pointer => return transCreateNodeNotEqual(rp, scope, res.node, try transCreateNodeNullLiteral(rp.c)), | 1289 | .Pointer => { |
| 1440 | | 1290 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| | 1291 | const rhs_node = try transCreateNodeNullLiteral(rp.c); |
| | 1292 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, grouped); |
| | 1293 | }, |
| 1441 | .Typedef => { | 1294 | .Typedef => { |
| 1442 | return transCreateNodeNotEqual(rp, scope, res.node, try transCreateNodeInt(rp.c, 0)); // TODO currently assuming it is like an int/char/bool builtin type. Coerce the type and recurse? Add a toTypedefZeroCmp function? | 1295 | const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty); |
| 1443 | | 1296 | const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); |
| 1444 | // TODO This is the code that was in translate-c, but it seems like it is giving wrong results! It just prints the typedef name instead of the value | 1297 | const underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); |
| 1445 | // const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty); | 1298 | return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(underlying_type), node, used, grouped); |
| 1446 | // const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); | | |
| 1447 | // const typedef_name_decl = ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl); | | |
| 1448 | | | |
| 1449 | // const typedef_name = if (rp.c.decl_table.get(@ptrToInt(typedef_name_decl))) |existing_entry| | | |
| 1450 | // existing_entry.value | | |
| 1451 | // else | | |
| 1452 | // try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_name_decl))); | | |
| 1453 | | | |
| 1454 | // return transCreateNodeIdentifier(rp.c, typedef_name); | | |
| 1455 | }, | 1299 | }, |
| 1456 | | | |
| 1457 | .Enum => { | 1300 | .Enum => { |
| 1458 | const gen_enum_decl_node = struct { | 1301 | const enum_ty = @ptrCast(*const ZigClangEnumType, ty); |
| 1459 | // Have to use a callback because node must be generated inline in order to avoid weird AST printing behavior, | 1302 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt"); |
| 1460 | // and the code to generate the nodes is a little different for each case | 1303 | try builtin_node.params.push(node); |
| 1461 | fn generate_node(inner_rp: RestorePoint, enum_ty: *const struct_ZigClangType, source_loc: ZigClangSourceLocation) TransError!*ast.Node { | 1304 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1462 | const actual_enum_ty = @ptrCast(*const ZigClangEnumType, enum_ty); | | |
| 1463 | const enum_decl = ZigClangEnumType_getDecl(actual_enum_ty); | | |
| 1464 | const enum_type = (try transEnumDecl(inner_rp.c, enum_decl)) orelse { | | |
| 1465 | return revertAndWarn(inner_rp, error.UnsupportedType, source_loc, "unable to translate enum declaration", .{}); | | |
| 1466 | }; | | |
| 1467 | return enum_type; | | |
| 1468 | } | | |
| 1469 | }; | | |
| 1470 | | 1305 | |
| 1471 | return toEnumZeroCmp(rp, scope, res.node, gen_enum_decl_node.generate_node, ty, ZigClangExpr_getBeginLoc(expr)); | 1306 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| | 1307 | const rhs_node = try transCreateNodeInt(rp.c, 0); |
| | 1308 | return transCreateNodeInfixOp(rp, scope, &builtin_node.base, .BangEqual, op_token, rhs_node, used, grouped); |
| 1472 | }, | 1309 | }, |
| 1473 | | | |
| 1474 | .Elaborated => { | 1310 | .Elaborated => { |
| 1475 | const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty); | 1311 | const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty); |
| 1476 | | 1312 | const named_type = ZigClangElaboratedType_getNamedType(elaborated_ty); |
| 1477 | switch (ZigClangElaboratedType_getKeyword(elaborated_ty)) { | 1313 | return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(named_type), node, used, grouped); |
| 1478 | .Enum => { | | |
| 1479 | // Have to use a callback because node must be generated inline in order to avoid weird AST printing behavior, | | |
| 1480 | // and the code to generate the nodes is a little different for each case | | |
| 1481 | const gen_enum_type_node = struct { | | |
| 1482 | fn generate_node(inner_rp: RestorePoint, enum_ty: *const struct_ZigClangType, source_loc: ZigClangSourceLocation) TransError!*ast.Node { | | |
| 1483 | const inner_elaborated_ty = @ptrCast(*const ZigClangElaboratedType, enum_ty); | | |
| 1484 | const enum_type = try transQualType(inner_rp, ZigClangElaboratedType_getNamedType(inner_elaborated_ty), source_loc); | | |
| 1485 | return enum_type; | | |
| 1486 | } | | |
| 1487 | }; | | |
| 1488 | | | |
| 1489 | return toEnumZeroCmp(rp, scope, res.node, gen_enum_type_node.generate_node, ty, ZigClangExpr_getBeginLoc(expr)); | | |
| 1490 | }, | | |
| 1491 | | | |
| 1492 | .Struct, | | |
| 1493 | .Union, | | |
| 1494 | .Interface, | | |
| 1495 | .Class, | | |
| 1496 | .Typename, | | |
| 1497 | .None, | | |
| 1498 | => return res.node, | | |
| 1499 | | | |
| 1500 | else => {}, | | |
| 1501 | } | | |
| 1502 | }, | 1314 | }, |
| 1503 | | 1315 | else => {}, |
| 1504 | .FunctionProto, | | |
| 1505 | .Record, | | |
| 1506 | .ConstantArray, | | |
| 1507 | .Paren, | | |
| 1508 | .Decayed, | | |
| 1509 | .Attributed, | | |
| 1510 | .IncompleteArray, | | |
| 1511 | .BlockPointer, | | |
| 1512 | .LValueReference, | | |
| 1513 | .RValueReference, | | |
| 1514 | .MemberPointer, | | |
| 1515 | .VariableArray, | | |
| 1516 | .DependentSizedArray, | | |
| 1517 | .DependentSizedExtVector, | | |
| 1518 | .Vector, | | |
| 1519 | .ExtVector, | | |
| 1520 | .FunctionNoProto, | | |
| 1521 | .UnresolvedUsing, | | |
| 1522 | .Adjusted, | | |
| 1523 | .TypeOfExpr, | | |
| 1524 | .TypeOf, | | |
| 1525 | .Decltype, | | |
| 1526 | .UnaryTransform, | | |
| 1527 | .TemplateTypeParm, | | |
| 1528 | .SubstTemplateTypeParm, | | |
| 1529 | .SubstTemplateTypeParmPack, | | |
| 1530 | .TemplateSpecialization, | | |
| 1531 | .Auto, | | |
| 1532 | .InjectedClassName, | | |
| 1533 | .DependentName, | | |
| 1534 | .DependentTemplateSpecialization, | | |
| 1535 | .PackExpansion, | | |
| 1536 | .ObjCObject, | | |
| 1537 | .ObjCInterface, | | |
| 1538 | .Complex, | | |
| 1539 | .ObjCObjectPointer, | | |
| 1540 | .Atomic, | | |
| 1541 | .Pipe, | | |
| 1542 | .ObjCTypeParam, | | |
| 1543 | .DeducedTemplateSpecialization, | | |
| 1544 | .DependentAddressSpace, | | |
| 1545 | .DependentVector, | | |
| 1546 | .MacroQualified, | | |
| 1547 | => return res.node, | | |
| 1548 | | | |
| 1549 | else => unreachable, | | |
| 1550 | } | 1316 | } |
| 1551 | | 1317 | return revertAndWarn(rp, error.UnsupportedType, loc, "unsupported bool expression type", .{}); |
| 1552 | unreachable; | | |
| 1553 | } | 1318 | } |
| 1554 | | 1319 | |
| 1555 | fn transIntegerLiteral( | 1320 | fn transIntegerLiteral( |
| ... | @@ -2036,7 +1801,6 @@ fn transSwitch( | ... | @@ -2036,7 +1801,6 @@ fn transSwitch( |
| 2036 | const switch_block = try transCreateNodeBlock(rp.c, null); | 1801 | const switch_block = try transCreateNodeBlock(rp.c, null); |
| 2037 | try switch_block.statements.push(&switch_node.base); | 1802 | try switch_block.statements.push(&switch_node.base); |
| 2038 | switch_scope.pending_block = switch_block; | 1803 | switch_scope.pending_block = switch_block; |
| 2039 | | | |
| 2040 | | 1804 | |
| 2041 | const last = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value); | 1805 | const last = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value); |
| 2042 | _ = try appendToken(rp.c, .Semicolon, ";"); | 1806 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| ... | @@ -2085,7 +1849,6 @@ fn transCase( | ... | @@ -2085,7 +1849,6 @@ fn transCase( |
| 2085 | } else | 1849 | } else |
| 2086 | try transExpr(rp, scope, ZigClangCaseStmt_getLHS(stmt), .used, .r_value); | 1850 | try transExpr(rp, scope, ZigClangCaseStmt_getLHS(stmt), .used, .r_value); |
| 2087 | | 1851 | |
| 2088 | | | |
| 2089 | const switch_prong = try transCreateNodeSwitchCase(rp.c, expr); | 1852 | const switch_prong = try transCreateNodeSwitchCase(rp.c, expr); |
| 2090 | switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base; | 1853 | switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base; |
| 2091 | _ = try appendToken(rp.c, .Comma, ","); | 1854 | _ = try appendToken(rp.c, .Comma, ","); |
| ... | @@ -2271,7 +2034,7 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla | ... | @@ -2271,7 +2034,7 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla |
| 2271 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); | 2034 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); |
| 2272 | grouped_expr.* = .{ | 2035 | grouped_expr.* = .{ |
| 2273 | .lparen = lparen, | 2036 | .lparen = lparen, |
| 2274 | .expr = &if_node.base, | 2037 | .expr = &if_node.base, |
| 2275 | .rparen = rparen, | 2038 | .rparen = rparen, |
| 2276 | }; | 2039 | }; |
| 2277 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); | 2040 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); |
| ... | @@ -2670,87 +2433,64 @@ fn transCreateNodePrefixOp( | ... | @@ -2670,87 +2433,64 @@ fn transCreateNodePrefixOp( |
| 2670 | return node; | 2433 | return node; |
| 2671 | } | 2434 | } |
| 2672 | | 2435 | |
| 2673 | fn transCreateNodeInfixOpImpl( | 2436 | fn transCreateNodeInfixOp( |
| 2674 | rp: RestorePoint, | 2437 | rp: RestorePoint, |
| 2675 | scope: *Scope, | 2438 | scope: *Scope, |
| 2676 | lhs_node: *ast.Node, | 2439 | lhs_node: *ast.Node, |
| 2677 | rhs_node: *ast.Node, | | |
| 2678 | op: ast.Node.InfixOp.Op, | 2440 | op: ast.Node.InfixOp.Op, |
| 2679 | op_tok_id: std.zig.Token.Id, | 2441 | op_token: ast.TokenIndex, |
| 2680 | bytes: []const u8, | 2442 | rhs_node: *ast.Node, |
| | 2443 | used: ResultUsed, |
| 2681 | grouped: bool, | 2444 | grouped: bool, |
| 2682 | ) !*ast.Node { | 2445 | ) !*ast.Node { |
| 2683 | const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined; | 2446 | var lparen = if (grouped) |
| 2684 | const op_token = try appendToken(rp.c, op_tok_id, bytes); | 2447 | try appendToken(rp.c, .LParen, "(") |
| | 2448 | else |
| | 2449 | null; |
| 2685 | const node = try rp.c.a().create(ast.Node.InfixOp); | 2450 | const node = try rp.c.a().create(ast.Node.InfixOp); |
| 2686 | node.* = ast.Node.InfixOp{ | 2451 | node.* = .{ |
| 2687 | .op_token = op_token, | 2452 | .op_token = op_token, |
| 2688 | .lhs = lhs_node, | 2453 | .lhs = lhs_node, |
| 2689 | .op = op, | 2454 | .op = op, |
| 2690 | .rhs = rhs_node, | 2455 | .rhs = rhs_node, |
| 2691 | }; | 2456 | }; |
| 2692 | if (!grouped) return &node.base; | 2457 | if (!grouped) return maybeSuppressResult(rp, scope, used, &node.base); |
| 2693 | const rparen = try appendToken(rp.c, .RParen, ")"); | 2458 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| 2694 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); | 2459 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); |
| 2695 | grouped_expr.* = .{ | 2460 | grouped_expr.* = .{ |
| 2696 | .lparen = lparen, | 2461 | .lparen = lparen.?, |
| 2697 | .expr = &node.base, | 2462 | .expr = &node.base, |
| 2698 | .rparen = rparen, | 2463 | .rparen = rparen, |
| 2699 | }; | 2464 | }; |
| 2700 | return &grouped_expr.base; | 2465 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); |
| 2701 | } | 2466 | } |
| 2702 | | 2467 | |
| 2703 | fn transCreateNodeInfixOp( | 2468 | fn transCreateNodeBoolInfixOp( |
| 2704 | rp: RestorePoint, | 2469 | rp: RestorePoint, |
| 2705 | scope: *Scope, | 2470 | scope: *Scope, |
| 2706 | stmt: *const ZigClangBinaryOperator, | 2471 | stmt: *const ZigClangBinaryOperator, |
| 2707 | op: ast.Node.InfixOp.Op, | 2472 | op: ast.Node.InfixOp.Op, |
| 2708 | op_tok_id: std.zig.Token.Id, | 2473 | used: ResultUsed, |
| 2709 | bytes: []const u8, | | |
| 2710 | grouped: bool, | 2474 | grouped: bool, |
| 2711 | ) !*ast.Node { | 2475 | ) !*ast.Node { |
| 2712 | return transCreateNodeInfixOpImpl( | 2476 | std.debug.assert(op == .BoolAnd or op == .BoolOr); |
| 2713 | rp, | | |
| 2714 | scope, | | |
| 2715 | (try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .r_value)).node, | | |
| 2716 | (try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value)).node, | | |
| 2717 | op, | | |
| 2718 | op_tok_id, | | |
| 2719 | bytes, | | |
| 2720 | grouped, | | |
| 2721 | ); | | |
| 2722 | } | | |
| 2723 | | | |
| 2724 | fn transCreateNodeNotEqual( | | |
| 2725 | rp: RestorePoint, | | |
| 2726 | scope: *Scope, | | |
| 2727 | lhs_node: *ast.Node, | | |
| 2728 | rhs_node: *ast.Node, | | |
| 2729 | ) !*ast.Node { | | |
| 2730 | return transCreateNodeInfixOpImpl(rp, scope, lhs_node, rhs_node, .BangEqual, .BangEqual, "!=", true); | | |
| 2731 | } | | |
| 2732 | | 2477 | |
| 2733 | fn transCreateNodeBoolInfixOp( | 2478 | const lhs_hode = try transBoolExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value, true); |
| 2734 | rp: RestorePoint, | 2479 | const op_token = if (op == .BoolAnd) |
| 2735 | scope: *Scope, | 2480 | try appendToken(rp.c, .Keyword_and, "and") |
| 2736 | stmt: *const ZigClangBinaryOperator, | 2481 | else |
| 2737 | comptime op: ast.Node.InfixOp.Op, | 2482 | try appendToken(rp.c, .Keyword_or, "or"); |
| 2738 | comptime op_tok_id: std.zig.Token.Id, | 2483 | const rhs = try transBoolExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value, true); |
| 2739 | comptime bytes: []const u8, | | |
| 2740 | ) !*ast.Node { | | |
| 2741 | if (!(op == .BoolAnd or op == .BoolOr)) { | | |
| 2742 | @compileError("op must be either .BoolAnd or .BoolOr"); | | |
| 2743 | } | | |
| 2744 | | 2484 | |
| 2745 | return transCreateNodeInfixOpImpl( | 2485 | return transCreateNodeInfixOp( |
| 2746 | rp, | 2486 | rp, |
| 2747 | scope, | 2487 | scope, |
| 2748 | try transBoolExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .r_value), | 2488 | lhs_hode, |
| 2749 | try transBoolExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value), | | |
| 2750 | op, | 2489 | op, |
| 2751 | op_tok_id, | 2490 | op_token, |
| 2752 | bytes, | 2491 | rhs, |
| 2753 | true, | 2492 | used, |
| | 2493 | grouped, |
| 2754 | ); | 2494 | ); |
| 2755 | } | 2495 | } |
| 2756 | | 2496 | |
| ... | @@ -3149,16 +2889,14 @@ fn transCreateNodeShiftOp( | ... | @@ -3149,16 +2889,14 @@ fn transCreateNodeShiftOp( |
| 3149 | comptime op_tok_id: std.zig.Token.Id, | 2889 | comptime op_tok_id: std.zig.Token.Id, |
| 3150 | comptime bytes: []const u8, | 2890 | comptime bytes: []const u8, |
| 3151 | ) !*ast.Node { | 2891 | ) !*ast.Node { |
| 3152 | if (!(op == .BitShiftLeft or op == .BitShiftRight)) { | 2892 | std.debug.assert(op == .BitShiftLeft or op == .BitShiftRight); |
| 3153 | @compileError("op must be either .BitShiftLeft or .BitShiftRight"); | | |
| 3154 | } | | |
| 3155 | | 2893 | |
| 3156 | const lhs_expr = ZigClangBinaryOperator_getLHS(stmt); | 2894 | const lhs_expr = ZigClangBinaryOperator_getLHS(stmt); |
| 3157 | const rhs_expr = ZigClangBinaryOperator_getRHS(stmt); | 2895 | const rhs_expr = ZigClangBinaryOperator_getRHS(stmt); |
| 3158 | const rhs_location = ZigClangExpr_getBeginLoc(rhs_expr); | 2896 | const rhs_location = ZigClangExpr_getBeginLoc(rhs_expr); |
| 3159 | // lhs >> u5(rh) | 2897 | // lhs >> u5(rh) |
| 3160 | | 2898 | |
| 3161 | const lhs = try transExpr(rp, scope, lhs_expr, .used, .r_value); | 2899 | const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value); |
| 3162 | const op_token = try appendToken(rp.c, op_tok_id, bytes); | 2900 | const op_token = try appendToken(rp.c, op_tok_id, bytes); |
| 3163 | | 2901 | |
| 3164 | const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 2902 | const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); |
| ... | @@ -3166,13 +2904,13 @@ fn transCreateNodeShiftOp( | ... | @@ -3166,13 +2904,13 @@ fn transCreateNodeShiftOp( |
| 3166 | try as_node.params.push(rhs_type); | 2904 | try as_node.params.push(rhs_type); |
| 3167 | _ = try appendToken(rp.c, .Comma, ","); | 2905 | _ = try appendToken(rp.c, .Comma, ","); |
| 3168 | const rhs = try transExpr(rp, scope, rhs_expr, .used, .r_value); | 2906 | const rhs = try transExpr(rp, scope, rhs_expr, .used, .r_value); |
| 3169 | try as_node.params.push(rhs.node); | 2907 | try as_node.params.push(rhs); |
| 3170 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2908 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3171 | | 2909 | |
| 3172 | const node = try rp.c.a().create(ast.Node.InfixOp); | 2910 | const node = try rp.c.a().create(ast.Node.InfixOp); |
| 3173 | node.* = ast.Node.InfixOp{ | 2911 | node.* = ast.Node.InfixOp{ |
| 3174 | .op_token = op_token, | 2912 | .op_token = op_token, |
| 3175 | .lhs = lhs.node, | 2913 | .lhs = lhs, |
| 3176 | .op = op, | 2914 | .op = op, |
| 3177 | .rhs = &as_node.base, | 2915 | .rhs = &as_node.base, |
| 3178 | }; | 2916 | }; |
| ... | @@ -3648,26 +3386,26 @@ fn isZigPrimitiveType(name: []const u8) bool { | ... | @@ -3648,26 +3386,26 @@ fn isZigPrimitiveType(name: []const u8) bool { |
| 3648 | } | 3386 | } |
| 3649 | // void is invalid in c so it doesn't need to be checked. | 3387 | // void is invalid in c so it doesn't need to be checked. |
| 3650 | return std.mem.eql(u8, name, "comptime_float") or | 3388 | return std.mem.eql(u8, name, "comptime_float") or |
| 3651 | std.mem.eql(u8, name, "comptime_int") or | 3389 | std.mem.eql(u8, name, "comptime_int") or |
| 3652 | std.mem.eql(u8, name, "bool") or | 3390 | std.mem.eql(u8, name, "bool") or |
| 3653 | std.mem.eql(u8, name, "isize") or | 3391 | std.mem.eql(u8, name, "isize") or |
| 3654 | std.mem.eql(u8, name, "usize") or | 3392 | std.mem.eql(u8, name, "usize") or |
| 3655 | std.mem.eql(u8, name, "f16") or | 3393 | std.mem.eql(u8, name, "f16") or |
| 3656 | std.mem.eql(u8, name, "f32") or | 3394 | std.mem.eql(u8, name, "f32") or |
| 3657 | std.mem.eql(u8, name, "f64") or | 3395 | std.mem.eql(u8, name, "f64") or |
| 3658 | std.mem.eql(u8, name, "f128") or | 3396 | std.mem.eql(u8, name, "f128") or |
| 3659 | std.mem.eql(u8, name, "c_longdouble") or | 3397 | std.mem.eql(u8, name, "c_longdouble") or |
| 3660 | std.mem.eql(u8, name, "noreturn") or | 3398 | std.mem.eql(u8, name, "noreturn") or |
| 3661 | std.mem.eql(u8, name, "type") or | 3399 | std.mem.eql(u8, name, "type") or |
| 3662 | std.mem.eql(u8, name, "anyerror") or | 3400 | std.mem.eql(u8, name, "anyerror") or |
| 3663 | std.mem.eql(u8, name, "c_short") or | 3401 | std.mem.eql(u8, name, "c_short") or |
| 3664 | std.mem.eql(u8, name, "c_ushort") or | 3402 | std.mem.eql(u8, name, "c_ushort") or |
| 3665 | std.mem.eql(u8, name, "c_int") or | 3403 | std.mem.eql(u8, name, "c_int") or |
| 3666 | std.mem.eql(u8, name, "c_uint") or | 3404 | std.mem.eql(u8, name, "c_uint") or |
| 3667 | std.mem.eql(u8, name, "c_long") or | 3405 | std.mem.eql(u8, name, "c_long") or |
| 3668 | std.mem.eql(u8, name, "c_ulong") or | 3406 | std.mem.eql(u8, name, "c_ulong") or |
| 3669 | std.mem.eql(u8, name, "c_longlong") or | 3407 | std.mem.eql(u8, name, "c_longlong") or |
| 3670 | std.mem.eql(u8, name, "c_ulonglong"); | 3408 | std.mem.eql(u8, name, "c_ulonglong"); |
| 3671 | } | 3409 | } |
| 3672 | | 3410 | |
| 3673 | fn isValidZigIdentifier(name: []const u8) bool { | 3411 | fn isValidZigIdentifier(name: []const u8) bool { |