| author | |
| committer | |
| log | c558a1ae26eaa8c59e97e80ec01990e35ef50f3a |
| tree | d2afebf241d8cd363ca00b71e02f6137e1a44333 |
| parent | 9a9441568070320d6549fe286300b45ffffd7b4d |
Enables translation of C code that uses the `_Generic` keyword5 files changed, 58 insertions(+), 0 deletions(-)
src/clang.zig+5| ... | @@ -537,6 +537,11 @@ pub const FunctionType = opaque { | ... | @@ -537,6 +537,11 @@ pub const FunctionType = opaque { |
| 537 | extern fn ZigClangFunctionType_getReturnType(*const FunctionType) QualType; | 537 | extern fn ZigClangFunctionType_getReturnType(*const FunctionType) QualType; |
| 538 | }; | 538 | }; |
| 539 | 539 | ||
| 540 | pub const GenericSelectionExpr = opaque { | ||
| 541 | pub const getResultExpr = ZigClangGenericSelectionExpr_getResultExpr; | ||
| 542 | extern fn ZigClangGenericSelectionExpr_getResultExpr(*const GenericSelectionExpr) *const Expr; | ||
| 543 | }; | ||
| 544 | |||
| 540 | pub const IfStmt = opaque { | 545 | pub const IfStmt = opaque { |
| 541 | pub const getThen = ZigClangIfStmt_getThen; | 546 | pub const getThen = ZigClangIfStmt_getThen; |
| 542 | extern fn ZigClangIfStmt_getThen(*const IfStmt) *const Stmt; | 547 | extern fn ZigClangIfStmt_getThen(*const IfStmt) *const Stmt; |
src/translate_c.zig+12| ... | @@ -1058,6 +1058,10 @@ fn transStmt( | ... | @@ -1058,6 +1058,10 @@ fn transStmt( |
| 1058 | const compound_literal = @ptrCast(*const clang.CompoundLiteralExpr, stmt); | 1058 | const compound_literal = @ptrCast(*const clang.CompoundLiteralExpr, stmt); |
| 1059 | return transExpr(c, scope, compound_literal.getInitializer(), result_used); | 1059 | return transExpr(c, scope, compound_literal.getInitializer(), result_used); |
| 1060 | }, | 1060 | }, |
| 1061 | .GenericSelectionExprClass => { | ||
| 1062 | const gen_sel = @ptrCast(*const clang.GenericSelectionExpr, stmt); | ||
| 1063 | return transExpr(c, scope, gen_sel.getResultExpr(), result_used); | ||
| 1064 | }, | ||
| 1061 | else => { | 1065 | else => { |
| 1062 | return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)}); | 1066 | return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)}); |
| 1063 | }, | 1067 | }, |
| ... | @@ -1582,6 +1586,10 @@ fn exprIsNarrowStringLiteral(expr: *const clang.Expr) bool { | ... | @@ -1582,6 +1586,10 @@ fn exprIsNarrowStringLiteral(expr: *const clang.Expr) bool { |
| 1582 | const op_expr = @ptrCast(*const clang.ParenExpr, expr).getSubExpr(); | 1586 | const op_expr = @ptrCast(*const clang.ParenExpr, expr).getSubExpr(); |
| 1583 | return exprIsNarrowStringLiteral(op_expr); | 1587 | return exprIsNarrowStringLiteral(op_expr); |
| 1584 | }, | 1588 | }, |
| 1589 | .GenericSelectionExprClass => { | ||
| 1590 | const gen_sel = @ptrCast(*const clang.GenericSelectionExpr, expr); | ||
| 1591 | return exprIsNarrowStringLiteral(gen_sel.getResultExpr()); | ||
| 1592 | }, | ||
| 1585 | else => return false, | 1593 | else => return false, |
| 1586 | } | 1594 | } |
| 1587 | } | 1595 | } |
| ... | @@ -2726,6 +2734,10 @@ fn cIsFunctionDeclRef(expr: *const clang.Expr) bool { | ... | @@ -2726,6 +2734,10 @@ fn cIsFunctionDeclRef(expr: *const clang.Expr) bool { |
| 2726 | const opcode = un_op.getOpcode(); | 2734 | const opcode = un_op.getOpcode(); |
| 2727 | return (opcode == .AddrOf or opcode == .Deref) and cIsFunctionDeclRef(un_op.getSubExpr()); | 2735 | return (opcode == .AddrOf or opcode == .Deref) and cIsFunctionDeclRef(un_op.getSubExpr()); |
| 2728 | }, | 2736 | }, |
| 2737 | .GenericSelectionExprClass => { | ||
| 2738 | const gen_sel = @ptrCast(*const clang.GenericSelectionExpr, expr); | ||
| 2739 | return cIsFunctionDeclRef(gen_sel.getResultExpr()); | ||
| 2740 | }, | ||
| 2729 | else => return false, | 2741 | else => return false, |
| 2730 | } | 2742 | } |
| 2731 | } | 2743 | } |
src/zig_clang.cpp+5| ... | @@ -2445,6 +2445,11 @@ struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClang | ... | @@ -2445,6 +2445,11 @@ struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClang |
| 2445 | return bitcast(casted->getReturnType()); | 2445 | return bitcast(casted->getReturnType()); |
| 2446 | } | 2446 | } |
| 2447 | 2447 | ||
| 2448 | const struct ZigClangExpr *ZigClangGenericSelectionExpr_getResultExpr(const struct ZigClangGenericSelectionExpr *self) { | ||
| 2449 | auto casted = reinterpret_cast<const clang::GenericSelectionExpr *>(self); | ||
| 2450 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getResultExpr()); | ||
| 2451 | } | ||
| 2452 | |||
| 2448 | bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self) { | 2453 | bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self) { |
| 2449 | auto casted = reinterpret_cast<const clang::FunctionProtoType *>(self); | 2454 | auto casted = reinterpret_cast<const clang::FunctionProtoType *>(self); |
| 2450 | return casted->isVariadic(); | 2455 | return casted->isVariadic(); |
src/zig_clang.h+2| ... | @@ -1116,6 +1116,8 @@ ZIG_EXTERN_C bool ZigClangFunctionType_getNoReturnAttr(const struct ZigClangFunc | ... | @@ -1116,6 +1116,8 @@ ZIG_EXTERN_C bool ZigClangFunctionType_getNoReturnAttr(const struct ZigClangFunc |
| 1116 | ZIG_EXTERN_C enum ZigClangCallingConv ZigClangFunctionType_getCallConv(const struct ZigClangFunctionType *self); | 1116 | ZIG_EXTERN_C enum ZigClangCallingConv ZigClangFunctionType_getCallConv(const struct ZigClangFunctionType *self); |
| 1117 | ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClangFunctionType *self); | 1117 | ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClangFunctionType *self); |
| 1118 | 1118 | ||
| 1119 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangGenericSelectionExpr_getResultExpr(const struct ZigClangGenericSelectionExpr *self); | ||
| 1120 | |||
| 1119 | ZIG_EXTERN_C bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self); | 1121 | ZIG_EXTERN_C bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self); |
| 1120 | ZIG_EXTERN_C unsigned ZigClangFunctionProtoType_getNumParams(const struct ZigClangFunctionProtoType *self); | 1122 | ZIG_EXTERN_C unsigned ZigClangFunctionProtoType_getNumParams(const struct ZigClangFunctionProtoType *self); |
| 1121 | ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(const struct ZigClangFunctionProtoType *self, unsigned i); | 1123 | ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(const struct ZigClangFunctionProtoType *self, unsigned i); |
test/run_translated_c.zig+34| ... | @@ -1187,4 +1187,38 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { | ... | @@ -1187,4 +1187,38 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 1187 | \\ return 0; | 1187 | \\ return 0; |
| 1188 | \\} | 1188 | \\} |
| 1189 | , ""); | 1189 | , ""); |
| 1190 | |||
| 1191 | cases.add("Generic selections", | ||
| 1192 | \\#include <stdlib.h> | ||
| 1193 | \\#include <string.h> | ||
| 1194 | \\#include <stdint.h> | ||
| 1195 | \\#define my_generic_fn(X) _Generic((X), \ | ||
| 1196 | \\ int: abs, \ | ||
| 1197 | \\ char *: strlen, \ | ||
| 1198 | \\ size_t: malloc, \ | ||
| 1199 | \\ default: free \ | ||
| 1200 | \\)(X) | ||
| 1201 | \\#define my_generic_val(X) _Generic((X), \ | ||
| 1202 | \\ int: 1, \ | ||
| 1203 | \\ const char *: "bar" \ | ||
| 1204 | \\) | ||
| 1205 | \\int main(void) { | ||
| 1206 | \\ if (my_generic_val(100) != 1) abort(); | ||
| 1207 | \\ | ||
| 1208 | \\ const char *foo = "foo"; | ||
| 1209 | \\ const char *bar = my_generic_val(foo); | ||
| 1210 | \\ if (strcmp(bar, "bar") != 0) abort(); | ||
| 1211 | \\ | ||
| 1212 | \\ if (my_generic_fn(-42) != 42) abort(); | ||
| 1213 | \\ if (my_generic_fn("hello") != 5) abort(); | ||
| 1214 | \\ | ||
| 1215 | \\ size_t size = 8192; | ||
| 1216 | \\ uint8_t *mem = my_generic_fn(size); | ||
| 1217 | \\ memset(mem, 42, size); | ||
| 1218 | \\ if (mem[size - 1] != 42) abort(); | ||
| 1219 | \\ my_generic_fn(mem); | ||
| 1220 | \\ | ||
| 1221 | \\ return 0; | ||
| 1222 | \\} | ||
| 1223 | , ""); | ||
| 1190 | } | 1224 | } |