| ... | @@ -271,7 +271,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -271,7 +271,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 271 | const proto_node = switch (ZigClangType_getTypeClass(fn_type)) { | 271 | const proto_node = switch (ZigClangType_getTypeClass(fn_type)) { |
| 272 | .FunctionProto => blk: { | 272 | .FunctionProto => blk: { |
| 273 | const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type); | 273 | const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type); |
| 274 | break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) { | 274 | break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) { |
| 275 | error.UnsupportedType => { | 275 | error.UnsupportedType => { |
| 276 | return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function"); | 276 | return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function"); |
| 277 | }, | 277 | }, |
| ... | @@ -280,7 +280,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -280,7 +280,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 280 | }, | 280 | }, |
| 281 | .FunctionNoProto => blk: { | 281 | .FunctionNoProto => blk: { |
| 282 | const fn_no_proto_type = @ptrCast(*const ZigClangFunctionType, fn_type); | 282 | const fn_no_proto_type = @ptrCast(*const ZigClangFunctionType, fn_type); |
| 283 | break :blk transFnNoProto(rp, fn_no_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) { | 283 | break :blk transFnNoProto(rp, fn_no_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) { |
| 284 | error.UnsupportedType => { | 284 | error.UnsupportedType => { |
| 285 | return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function"); | 285 | return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function"); |
| 286 | }, | 286 | }, |
| ... | @@ -420,7 +420,6 @@ fn transCompoundStmtInline( | ... | @@ -420,7 +420,6 @@ fn transCompoundStmtInline( |
| 420 | while (it != end_it) : (it += 1) { | 420 | while (it != end_it) : (it += 1) { |
| 421 | const result = try transStmt(rp, parent_scope, it.*, .unused, .r_value); | 421 | const result = try transStmt(rp, parent_scope, it.*, .unused, .r_value); |
| 422 | scope = result.child_scope; | 422 | scope = result.child_scope; |
| 423 | std.debug.warn("id: {}\n", result.node.id); | | |
| 424 | if (result.node != &block_node.base) | 423 | if (result.node != &block_node.base) |
| 425 | try block_node.statements.push(result.node); | 424 | try block_node.statements.push(result.node); |
| 426 | } | 425 | } |
| ... | @@ -661,10 +660,13 @@ fn transCCast( | ... | @@ -661,10 +660,13 @@ fn transCCast( |
| 661 | if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type)) | 660 | if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type)) |
| 662 | return transCPtrCast(rp, loc, dst_type, src_type, expr); | 661 | return transCPtrCast(rp, loc, dst_type, src_type, expr); |
| 663 | if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) { | 662 | if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) { |
| | 663 | const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc)); |
| 664 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); | 664 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); |
| 665 | try builtin_node.params.push(expr); | 665 | try builtin_node.params.push(expr); |
| 666 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 666 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 667 | return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), &builtin_node.base)).base; | 667 | try cast_node.op.Call.params.push(&builtin_node.base); |
| | 668 | cast_node.rtoken = try appendToken(rp.c, .RParen, ")"); |
| | 669 | return &cast_node.base; |
| 668 | } | 670 | } |
| 669 | if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) { | 671 | if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) { |
| 670 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); | 672 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); |
| ... | @@ -677,7 +679,10 @@ fn transCCast( | ... | @@ -677,7 +679,10 @@ fn transCCast( |
| 677 | // TODO: maybe widen to increase size | 679 | // TODO: maybe widen to increase size |
| 678 | // TODO: maybe bitcast to change sign | 680 | // TODO: maybe bitcast to change sign |
| 679 | // TODO: maybe truncate to reduce size | 681 | // TODO: maybe truncate to reduce size |
| 680 | return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), expr)).base; | 682 | const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc)); |
| | 683 | try cast_node.op.Call.params.push(expr); |
| | 684 | cast_node.rtoken = try appendToken(rp.c, .RParen, ")"); |
| | 685 | return &cast_node.base; |
| 681 | } | 686 | } |
| 682 | | 687 | |
| 683 | fn transExpr( | 688 | fn transExpr( |
| ... | @@ -728,13 +733,15 @@ fn transCPtrCast( | ... | @@ -728,13 +733,15 @@ fn transCPtrCast( |
| 728 | // void has 1-byte alignment, so @alignCast is not needed | 733 | // void has 1-byte alignment, so @alignCast is not needed |
| 729 | try ptrcast_node.params.push(expr); | 734 | try ptrcast_node.params.push(expr); |
| 730 | } else { | 735 | } else { |
| | 736 | const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); |
| 731 | const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); | 737 | const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); |
| 732 | const child_type_node = try transQualType(rp, child_type, loc); | 738 | const child_type_node = try transQualType(rp, child_type, loc); |
| 733 | try alignof_node.params.push(child_type_node); | 739 | try alignof_node.params.push(child_type_node); |
| 734 | const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); | 740 | alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 735 | try aligncast_node.params.push(&alignof_node.base); | 741 | try aligncast_node.params.push(&alignof_node.base); |
| 736 | _ = try appendToken(rp.c, .Comma, ","); | 742 | _ = try appendToken(rp.c, .Comma, ","); |
| 737 | try aligncast_node.params.push(expr); | 743 | try aligncast_node.params.push(expr); |
| | 744 | aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 738 | try ptrcast_node.params.push(&aligncast_node.base); | 745 | try ptrcast_node.params.push(&aligncast_node.base); |
| 739 | } | 746 | } |
| 740 | ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 747 | ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | @@ -909,7 +916,7 @@ fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.Builti | ... | @@ -909,7 +916,7 @@ fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.Builti |
| 909 | return node; | 916 | return node; |
| 910 | } | 917 | } |
| 911 | | 918 | |
| 912 | fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) !*ast.Node.SuffixOp { | 919 | fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp { |
| 913 | _ = try appendToken(c, .LParen, "("); | 920 | _ = try appendToken(c, .LParen, "("); |
| 914 | const node = try c.a().create(ast.Node.SuffixOp); | 921 | const node = try c.a().create(ast.Node.SuffixOp); |
| 915 | node.* = ast.Node.SuffixOp{ | 922 | node.* = ast.Node.SuffixOp{ |
| ... | @@ -921,37 +928,34 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) | ... | @@ -921,37 +928,34 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) |
| 921 | .async_attr = null, | 928 | .async_attr = null, |
| 922 | }, | 929 | }, |
| 923 | }, | 930 | }, |
| 924 | .rtoken = try appendToken(c, .RParen, ")"), | 931 | .rtoken = undefined, // set after appending args |
| 925 | }; | 932 | }; |
| 926 | try node.op.Call.params.push(first_arg); | | |
| 927 | return node; | 933 | return node; |
| 928 | } | 934 | } |
| 929 | | 935 | |
| 930 | fn transCreateNodePrefixOp( | 936 | fn transCreateNodePrefixOp( |
| 931 | c: *Context, | 937 | c: *Context, |
| 932 | op: ast.Node.PrefixOp.Op, | 938 | op: ast.Node.PrefixOp.Op, |
| 933 | rhs: *ast.Node, | | |
| 934 | op_tok_id: std.zig.Token.Id, | 939 | op_tok_id: std.zig.Token.Id, |
| 935 | bytes: []const u8, | 940 | bytes: []const u8, |
| 936 | ) !*ast.Node { | 941 | ) !*ast.Node.PrefixOp { |
| 937 | const node = try c.a().create(ast.Node.PrefixOp); | 942 | const node = try c.a().create(ast.Node.PrefixOp); |
| 938 | node.* = ast.Node.PrefixOp{ | 943 | node.* = ast.Node.PrefixOp{ |
| 939 | .base = ast.Node{ .id = .PrefixOp }, | 944 | .base = ast.Node{ .id = .PrefixOp }, |
| 940 | .op_token = try appendToken(c, op_tok_id, bytes), | 945 | .op_token = try appendToken(c, op_tok_id, bytes), |
| 941 | .op = op, | 946 | .op = op, |
| 942 | .rhs = rhs, | 947 | .rhs = undefined, // translate and set afterward |
| 943 | }; | 948 | }; |
| 944 | return &node.base; | 949 | return node; |
| 945 | } | 950 | } |
| 946 | | 951 | |
| 947 | fn transCreateNodePtrType( | 952 | fn transCreateNodePtrType( |
| 948 | c: *Context, | 953 | c: *Context, |
| 949 | is_const: bool, | 954 | is_const: bool, |
| 950 | is_volatile: bool, | 955 | is_volatile: bool, |
| 951 | rhs: *ast.Node, | | |
| 952 | op_tok_id: std.zig.Token.Id, | 956 | op_tok_id: std.zig.Token.Id, |
| 953 | bytes: []const u8, | 957 | bytes: []const u8, |
| 954 | ) !*ast.Node { | 958 | ) !*ast.Node.PrefixOp { |
| 955 | const node = try c.a().create(ast.Node.PrefixOp); | 959 | const node = try c.a().create(ast.Node.PrefixOp); |
| 956 | node.* = ast.Node.PrefixOp{ | 960 | node.* = ast.Node.PrefixOp{ |
| 957 | .base = ast.Node{ .id = .PrefixOp }, | 961 | .base = ast.Node{ .id = .PrefixOp }, |
| ... | @@ -964,9 +968,9 @@ fn transCreateNodePtrType( | ... | @@ -964,9 +968,9 @@ fn transCreateNodePtrType( |
| 964 | .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null, | 968 | .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null, |
| 965 | }, | 969 | }, |
| 966 | }, | 970 | }, |
| 967 | .rhs = rhs, | 971 | .rhs = undefined, // translate and set afterward |
| 968 | }; | 972 | }; |
| 969 | return &node.base; | 973 | return node; |
| 970 | } | 974 | } |
| 971 | | 975 | |
| 972 | fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { | 976 | fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { |
| ... | @@ -1038,7 +1042,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour | ... | @@ -1038,7 +1042,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1038 | }, | 1042 | }, |
| 1039 | .FunctionProto => { | 1043 | .FunctionProto => { |
| 1040 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); | 1044 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); |
| 1041 | const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null); | 1045 | const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null, false); |
| 1042 | return &fn_proto.base; | 1046 | return &fn_proto.base; |
| 1043 | }, | 1047 | }, |
| 1044 | .Paren => { | 1048 | .Paren => { |
| ... | @@ -1047,28 +1051,33 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour | ... | @@ -1047,28 +1051,33 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1047 | }, | 1051 | }, |
| 1048 | .Pointer => { | 1052 | .Pointer => { |
| 1049 | const child_qt = ZigClangType_getPointeeType(ty); | 1053 | const child_qt = ZigClangType_getPointeeType(ty); |
| 1050 | const child_node = try transQualType(rp, child_qt, source_loc); | 1054 | if (qualTypeChildIsFnProto(child_qt)) { |
| 1051 | if (qualTypeChildIsFnProto(child_qt)) | 1055 | const optional_node = try transCreateNodePrefixOp(rp.c, .OptionalType, .QuestionMark, "?"); |
| 1052 | return transCreateNodePrefixOp(rp.c, .OptionalType, child_node, .QuestionMark, "?"); | 1056 | optional_node.rhs = try transQualType(rp, child_qt, source_loc); |
| | 1057 | return &optional_node.base; |
| | 1058 | } |
| 1053 | if (typeIsOpaque(rp.c, ZigClangQualType_getTypePtr(child_qt), source_loc)) { | 1059 | if (typeIsOpaque(rp.c, ZigClangQualType_getTypePtr(child_qt), source_loc)) { |
| | 1060 | const optional_node = try transCreateNodePrefixOp(rp.c, .OptionalType, .QuestionMark, "?"); |
| 1054 | const pointer_node = try transCreateNodePtrType( | 1061 | const pointer_node = try transCreateNodePtrType( |
| 1055 | rp.c, | 1062 | rp.c, |
| 1056 | ZigClangQualType_isConstQualified(child_qt), | 1063 | ZigClangQualType_isConstQualified(child_qt), |
| 1057 | ZigClangQualType_isVolatileQualified(child_qt), | 1064 | ZigClangQualType_isVolatileQualified(child_qt), |
| 1058 | child_node, | | |
| 1059 | .Asterisk, | 1065 | .Asterisk, |
| 1060 | "*", | 1066 | "*", |
| 1061 | ); | 1067 | ); |
| 1062 | return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node, .QuestionMark, "?"); | 1068 | optional_node.rhs = &pointer_node.base; |
| | 1069 | pointer_node.rhs = try transQualType(rp, child_qt, source_loc); |
| | 1070 | return &optional_node.base; |
| 1063 | } | 1071 | } |
| 1064 | return transCreateNodePtrType( | 1072 | const pointer_node = try transCreateNodePtrType( |
| 1065 | rp.c, | 1073 | rp.c, |
| 1066 | ZigClangQualType_isConstQualified(child_qt), | 1074 | ZigClangQualType_isConstQualified(child_qt), |
| 1067 | ZigClangQualType_isVolatileQualified(child_qt), | 1075 | ZigClangQualType_isVolatileQualified(child_qt), |
| 1068 | child_node, | | |
| 1069 | .BracketStarCBracket, | 1076 | .BracketStarCBracket, |
| 1070 | "[*c]", | 1077 | "[*c]", |
| 1071 | ); | 1078 | ); |
| | 1079 | pointer_node.rhs = try transQualType(rp, child_qt, source_loc); |
| | 1080 | return &pointer_node.base; |
| 1072 | }, | 1081 | }, |
| 1073 | else => { | 1082 | else => { |
| 1074 | const type_name = rp.c.str(ZigClangType_getTypeClassName(ty)); | 1083 | const type_name = rp.c.str(ZigClangType_getTypeClassName(ty)); |
| ... | @@ -1103,6 +1112,7 @@ fn transFnProto( | ... | @@ -1103,6 +1112,7 @@ fn transFnProto( |
| 1103 | fn_proto_ty: *const ZigClangFunctionProtoType, | 1112 | fn_proto_ty: *const ZigClangFunctionProtoType, |
| 1104 | source_loc: ZigClangSourceLocation, | 1113 | source_loc: ZigClangSourceLocation, |
| 1105 | fn_decl_context: ?FnDeclContext, | 1114 | fn_decl_context: ?FnDeclContext, |
| | 1115 | is_pub: bool, |
| 1106 | ) !*ast.Node.FnProto { | 1116 | ) !*ast.Node.FnProto { |
| 1107 | const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty); | 1117 | const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty); |
| 1108 | const cc = try transCC(rp, fn_ty, source_loc); | 1118 | const cc = try transCC(rp, fn_ty, source_loc); |
| ... | @@ -1113,7 +1123,7 @@ fn transFnProto( | ... | @@ -1113,7 +1123,7 @@ fn transFnProto( |
| 1113 | return revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO: implement parameters for FunctionProto in transType"); | 1123 | return revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO: implement parameters for FunctionProto in transType"); |
| 1114 | } | 1124 | } |
| 1115 | | 1125 | |
| 1116 | return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc); | 1126 | return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); |
| 1117 | } | 1127 | } |
| 1118 | | 1128 | |
| 1119 | fn transFnNoProto( | 1129 | fn transFnNoProto( |
| ... | @@ -1121,10 +1131,11 @@ fn transFnNoProto( | ... | @@ -1121,10 +1131,11 @@ fn transFnNoProto( |
| 1121 | fn_ty: *const ZigClangFunctionType, | 1131 | fn_ty: *const ZigClangFunctionType, |
| 1122 | source_loc: ZigClangSourceLocation, | 1132 | source_loc: ZigClangSourceLocation, |
| 1123 | fn_decl_context: ?FnDeclContext, | 1133 | fn_decl_context: ?FnDeclContext, |
| | 1134 | is_pub: bool, |
| 1124 | ) !*ast.Node.FnProto { | 1135 | ) !*ast.Node.FnProto { |
| 1125 | const cc = try transCC(rp, fn_ty, source_loc); | 1136 | const cc = try transCC(rp, fn_ty, source_loc); |
| 1126 | const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true; | 1137 | const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true; |
| 1127 | return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc); | 1138 | return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); |
| 1128 | } | 1139 | } |
| 1129 | | 1140 | |
| 1130 | fn finishTransFnProto( | 1141 | fn finishTransFnProto( |
| ... | @@ -1134,6 +1145,7 @@ fn finishTransFnProto( | ... | @@ -1134,6 +1145,7 @@ fn finishTransFnProto( |
| 1134 | fn_decl_context: ?FnDeclContext, | 1145 | fn_decl_context: ?FnDeclContext, |
| 1135 | is_var_args: bool, | 1146 | is_var_args: bool, |
| 1136 | cc: CallingConvention, | 1147 | cc: CallingConvention, |
| | 1148 | is_pub: bool, |
| 1137 | ) !*ast.Node.FnProto { | 1149 | ) !*ast.Node.FnProto { |
| 1138 | const is_export = if (fn_decl_context) |ctx| ctx.is_export else false; | 1150 | const is_export = if (fn_decl_context) |ctx| ctx.is_export else false; |
| 1139 | | 1151 | |
| ... | @@ -1141,7 +1153,7 @@ fn finishTransFnProto( | ... | @@ -1141,7 +1153,7 @@ fn finishTransFnProto( |
| 1141 | // TODO check for align attribute | 1153 | // TODO check for align attribute |
| 1142 | | 1154 | |
| 1143 | // pub extern fn name(...) T | 1155 | // pub extern fn name(...) T |
| 1144 | const pub_tok = try appendToken(rp.c, .Keyword_pub, "pub"); | 1156 | const pub_tok = if (is_pub) try appendToken(rp.c, .Keyword_pub, "pub") else null; |
| 1145 | const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null; | 1157 | const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null; |
| 1146 | const extern_export_inline_tok = if (is_export) | 1158 | const extern_export_inline_tok = if (is_export) |
| 1147 | try appendToken(rp.c, .Keyword_export, "export") | 1159 | try appendToken(rp.c, .Keyword_export, "export") |