| ... | @@ -2880,35 +2880,57 @@ fn transCPtrCast( | ... | @@ -2880,35 +2880,57 @@ fn transCPtrCast( |
| 2880 | ) !*ast.Node { | 2880 | ) !*ast.Node { |
| 2881 | const ty = ZigClangQualType_getTypePtr(dst_type); | 2881 | const ty = ZigClangQualType_getTypePtr(dst_type); |
| 2882 | const child_type = ZigClangType_getPointeeType(ty); | 2882 | const child_type = ZigClangType_getPointeeType(ty); |
| | 2883 | const src_ty = ZigClangQualType_getTypePtr(src_type); |
| | 2884 | const src_child_type = ZigClangType_getPointeeType(src_ty); |
| 2883 | | 2885 | |
| 2884 | // Implicit downcasting from higher to lower alignment values is forbidden, | 2886 | if ((ZigClangQualType_isConstQualified(src_child_type) and |
| 2885 | // use @alignCast to side-step this problem | 2887 | !ZigClangQualType_isConstQualified(child_type)) or |
| 2886 | const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast"); | 2888 | (ZigClangQualType_isVolatileQualified(src_child_type) and |
| 2887 | const dst_type_node = try transType(rp, ty, loc); | 2889 | !ZigClangQualType_isVolatileQualified(child_type))) |
| 2888 | try ptrcast_node.params.push(dst_type_node); | 2890 | { |
| 2889 | _ = try appendToken(rp.c, .Comma, ","); | 2891 | // Casting away const or volatile requires us to use @intToPtr |
| | 2892 | const inttoptr_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); |
| | 2893 | const dst_type_node = try transType(rp, ty, loc); |
| | 2894 | try inttoptr_node.params.push(dst_type_node); |
| | 2895 | _ = try appendToken(rp.c, .Comma, ","); |
| 2890 | | 2896 | |
| 2891 | if (ZigClangType_isVoidType(qualTypeCanon(child_type))) { | 2897 | const ptrtoint_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); |
| 2892 | // void has 1-byte alignment, so @alignCast is not needed | 2898 | try ptrtoint_node.params.push(expr); |
| 2893 | try ptrcast_node.params.push(expr); | 2899 | ptrtoint_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2894 | } else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) { | 2900 | |
| 2895 | // For opaque types a ptrCast is enough | 2901 | try inttoptr_node.params.push(&ptrtoint_node.base); |
| 2896 | try ptrcast_node.params.push(expr); | 2902 | inttoptr_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| | 2903 | return &inttoptr_node.base; |
| 2897 | } else { | 2904 | } else { |
| 2898 | const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); | 2905 | // Implicit downcasting from higher to lower alignment values is forbidden, |
| 2899 | const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); | 2906 | // use @alignCast to side-step this problem |
| 2900 | const child_type_node = try transQualType(rp, child_type, loc); | 2907 | const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast"); |
| 2901 | try alignof_node.params.push(child_type_node); | 2908 | const dst_type_node = try transType(rp, ty, loc); |
| 2902 | alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2909 | try ptrcast_node.params.push(dst_type_node); |
| 2903 | try aligncast_node.params.push(&alignof_node.base); | | |
| 2904 | _ = try appendToken(rp.c, .Comma, ","); | 2910 | _ = try appendToken(rp.c, .Comma, ","); |
| 2905 | try aligncast_node.params.push(expr); | | |
| 2906 | aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | | |
| 2907 | try ptrcast_node.params.push(&aligncast_node.base); | | |
| 2908 | } | | |
| 2909 | ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | | |
| 2910 | | 2911 | |
| 2911 | return &ptrcast_node.base; | 2912 | if (ZigClangType_isVoidType(qualTypeCanon(child_type))) { |
| | 2913 | // void has 1-byte alignment, so @alignCast is not needed |
| | 2914 | try ptrcast_node.params.push(expr); |
| | 2915 | } else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) { |
| | 2916 | // For opaque types a ptrCast is enough |
| | 2917 | try ptrcast_node.params.push(expr); |
| | 2918 | } else { |
| | 2919 | const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); |
| | 2920 | const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); |
| | 2921 | const child_type_node = try transQualType(rp, child_type, loc); |
| | 2922 | try alignof_node.params.push(child_type_node); |
| | 2923 | alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| | 2924 | try aligncast_node.params.push(&alignof_node.base); |
| | 2925 | _ = try appendToken(rp.c, .Comma, ","); |
| | 2926 | try aligncast_node.params.push(expr); |
| | 2927 | aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| | 2928 | try ptrcast_node.params.push(&aligncast_node.base); |
| | 2929 | } |
| | 2930 | ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| | 2931 | |
| | 2932 | return &ptrcast_node.base; |
| | 2933 | } |
| 2912 | } | 2934 | } |
| 2913 | | 2935 | |
| 2914 | fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node { | 2936 | fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node { |