Commit c558a1ae26
Changed files (5)
src/clang.zig
@@ -537,6 +537,11 @@ pub const FunctionType = opaque {
extern fn ZigClangFunctionType_getReturnType(*const FunctionType) QualType;
};
+pub const GenericSelectionExpr = opaque {
+ pub const getResultExpr = ZigClangGenericSelectionExpr_getResultExpr;
+ extern fn ZigClangGenericSelectionExpr_getResultExpr(*const GenericSelectionExpr) *const Expr;
+};
+
pub const IfStmt = opaque {
pub const getThen = ZigClangIfStmt_getThen;
extern fn ZigClangIfStmt_getThen(*const IfStmt) *const Stmt;
src/translate_c.zig
@@ -1058,6 +1058,10 @@ fn transStmt(
const compound_literal = @ptrCast(*const clang.CompoundLiteralExpr, stmt);
return transExpr(c, scope, compound_literal.getInitializer(), result_used);
},
+ .GenericSelectionExprClass => {
+ const gen_sel = @ptrCast(*const clang.GenericSelectionExpr, stmt);
+ return transExpr(c, scope, gen_sel.getResultExpr(), result_used);
+ },
else => {
return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)});
},
@@ -1582,6 +1586,10 @@ fn exprIsNarrowStringLiteral(expr: *const clang.Expr) bool {
const op_expr = @ptrCast(*const clang.ParenExpr, expr).getSubExpr();
return exprIsNarrowStringLiteral(op_expr);
},
+ .GenericSelectionExprClass => {
+ const gen_sel = @ptrCast(*const clang.GenericSelectionExpr, expr);
+ return exprIsNarrowStringLiteral(gen_sel.getResultExpr());
+ },
else => return false,
}
}
@@ -2726,6 +2734,10 @@ fn cIsFunctionDeclRef(expr: *const clang.Expr) bool {
const opcode = un_op.getOpcode();
return (opcode == .AddrOf or opcode == .Deref) and cIsFunctionDeclRef(un_op.getSubExpr());
},
+ .GenericSelectionExprClass => {
+ const gen_sel = @ptrCast(*const clang.GenericSelectionExpr, expr);
+ return cIsFunctionDeclRef(gen_sel.getResultExpr());
+ },
else => return false,
}
}
src/zig_clang.cpp
@@ -2445,6 +2445,11 @@ struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClang
return bitcast(casted->getReturnType());
}
+const struct ZigClangExpr *ZigClangGenericSelectionExpr_getResultExpr(const struct ZigClangGenericSelectionExpr *self) {
+ auto casted = reinterpret_cast<const clang::GenericSelectionExpr *>(self);
+ return reinterpret_cast<const struct ZigClangExpr *>(casted->getResultExpr());
+}
+
bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self) {
auto casted = reinterpret_cast<const clang::FunctionProtoType *>(self);
return casted->isVariadic();
src/zig_clang.h
@@ -1116,6 +1116,8 @@ ZIG_EXTERN_C bool ZigClangFunctionType_getNoReturnAttr(const struct ZigClangFunc
ZIG_EXTERN_C enum ZigClangCallingConv ZigClangFunctionType_getCallConv(const struct ZigClangFunctionType *self);
ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClangFunctionType *self);
+ZIG_EXTERN_C const struct ZigClangExpr *ZigClangGenericSelectionExpr_getResultExpr(const struct ZigClangGenericSelectionExpr *self);
+
ZIG_EXTERN_C bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self);
ZIG_EXTERN_C unsigned ZigClangFunctionProtoType_getNumParams(const struct ZigClangFunctionProtoType *self);
ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(const struct ZigClangFunctionProtoType *self, unsigned i);
test/run_translated_c.zig
@@ -1187,4 +1187,38 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
\\ return 0;
\\}
, "");
+
+ cases.add("Generic selections",
+ \\#include <stdlib.h>
+ \\#include <string.h>
+ \\#include <stdint.h>
+ \\#define my_generic_fn(X) _Generic((X), \
+ \\ int: abs, \
+ \\ char *: strlen, \
+ \\ size_t: malloc, \
+ \\ default: free \
+ \\)(X)
+ \\#define my_generic_val(X) _Generic((X), \
+ \\ int: 1, \
+ \\ const char *: "bar" \
+ \\)
+ \\int main(void) {
+ \\ if (my_generic_val(100) != 1) abort();
+ \\
+ \\ const char *foo = "foo";
+ \\ const char *bar = my_generic_val(foo);
+ \\ if (strcmp(bar, "bar") != 0) abort();
+ \\
+ \\ if (my_generic_fn(-42) != 42) abort();
+ \\ if (my_generic_fn("hello") != 5) abort();
+ \\
+ \\ size_t size = 8192;
+ \\ uint8_t *mem = my_generic_fn(size);
+ \\ memset(mem, 42, size);
+ \\ if (mem[size - 1] != 42) abort();
+ \\ my_generic_fn(mem);
+ \\
+ \\ return 0;
+ \\}
+ , "");
}