authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-04-22 02:11:16-04:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-04-23 21:45:08+03:00
log42ee364e7b698822a69cba4cd2bda17868657e05
tree4a69da6479fb97502dc83794e5d745e1fe3eb053
parentbc8e1e1de4a2f22c56528240d320f682f1ec4b69

translate-c: support brace-enclosed string initializers (c++20 9.4.2.1)


5 files changed, 61 insertions(+), 8 deletions(-)

src/clang.zig+9
...@@ -460,6 +460,9 @@ pub const Expr = opaque {...@@ -460,6 +460,9 @@ pub const Expr = opaque {
460460
461 pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;461 pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;
462 extern fn ZigClangExpr_EvaluateAsConstantExpr(*const Expr, *ExprEvalResult, Expr_ConstantExprKind, *const ASTContext) bool;462 extern fn ZigClangExpr_EvaluateAsConstantExpr(*const Expr, *ExprEvalResult, Expr_ConstantExprKind, *const ASTContext) bool;
463
464 pub const castToStringLiteral = ZigClangExpr_castToStringLiteral;
465 extern fn ZigClangExpr_castToStringLiteral(*const Expr) ?*const StringLiteral;
463};466};
464467
465pub const FieldDecl = opaque {468pub const FieldDecl = opaque {
...@@ -1053,6 +1056,12 @@ pub const InitListExpr = opaque {...@@ -1053,6 +1056,12 @@ pub const InitListExpr = opaque {
1053 pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller;1056 pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller;
1054 extern fn ZigClangInitListExpr_getArrayFiller(*const InitListExpr) *const Expr;1057 extern fn ZigClangInitListExpr_getArrayFiller(*const InitListExpr) *const Expr;
10551058
1059 pub const hasArrayFiller = ZigClangInitListExpr_hasArrayFiller;
1060 extern fn ZigClangInitListExpr_hasArrayFiller(*const InitListExpr) bool;
1061
1062 pub const isStringLiteralInit = ZigClangInitListExpr_isStringLiteralInit;
1063 extern fn ZigClangInitListExpr_isStringLiteralInit(*const InitListExpr) bool;
1064
1056 pub const getNumInits = ZigClangInitListExpr_getNumInits;1065 pub const getNumInits = ZigClangInitListExpr_getNumInits;
1057 extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint;1066 extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint;
10581067
src/translate_c.zig+27-8
...@@ -2697,6 +2697,13 @@ fn transInitListExprArray(...@@ -2697,6 +2697,13 @@ fn transInitListExprArray(
2697 return Tag.empty_array.create(c.arena, child_type);2697 return Tag.empty_array.create(c.arena, child_type);
2698 }2698 }
26992699
2700 if (expr.isStringLiteralInit()) {
2701 assert(init_count == 1);
2702 const init_expr = expr.getInit(0);
2703 const string_literal = init_expr.castToStringLiteral().?;
2704 return try transStringLiteral(c, scope, string_literal, .used);
2705 }
2706
2700 const init_node = if (init_count != 0) blk: {2707 const init_node = if (init_count != 0) blk: {
2701 const init_list = try c.arena.alloc(Node, init_count);2708 const init_list = try c.arena.alloc(Node, init_count);
27022709
...@@ -2714,6 +2721,7 @@ fn transInitListExprArray(...@@ -2714,6 +2721,7 @@ fn transInitListExprArray(
2714 break :blk init_node;2721 break :blk init_node;
2715 } else null;2722 } else null;
27162723
2724 assert(expr.hasArrayFiller());
2717 const filler_val_expr = expr.getArrayFiller();2725 const filler_val_expr = expr.getArrayFiller();
2718 const filler_node = try Tag.array_filler.create(c.arena, .{2726 const filler_node = try Tag.array_filler.create(c.arena, .{
2719 .type = child_type,2727 .type = child_type,
...@@ -4176,6 +4184,17 @@ fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {...@@ -4176,6 +4184,17 @@ fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
4176 try c.global_scope.nodes.append(decl_node);4184 try c.global_scope.nodes.append(decl_node);
4177}4185}
41784186
4187fn transQualTypeInitializedStringLiteral(c: *Context, elem_ty: Node, string_lit: *const clang.StringLiteral) TypeError!Node {
4188 const string_lit_size = string_lit.getLength();
4189 const array_size = @intCast(usize, string_lit_size);
4190
4191 // incomplete array initialized with empty string, will be translated as [1]T{0}
4192 // see https://github.com/ziglang/zig/issues/8256
4193 if (array_size == 0) return Tag.array_type.create(c.arena, .{ .len = 1, .elem_type = elem_ty });
4194
4195 return Tag.null_sentinel_array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
4196}
4197
4179/// Translate a qualtype for a variable with an initializer. This only matters4198/// Translate a qualtype for a variable with an initializer. This only matters
4180/// for incomplete arrays, since the initializer determines the size of the array.4199/// for incomplete arrays, since the initializer determines the size of the array.
4181fn transQualTypeInitialized(4200fn transQualTypeInitialized(
...@@ -4193,18 +4212,18 @@ fn transQualTypeInitialized(...@@ -4193,18 +4212,18 @@ fn transQualTypeInitialized(
4193 switch (decl_init.getStmtClass()) {4212 switch (decl_init.getStmtClass()) {
4194 .StringLiteralClass => {4213 .StringLiteralClass => {
4195 const string_lit = @ptrCast(*const clang.StringLiteral, decl_init);4214 const string_lit = @ptrCast(*const clang.StringLiteral, decl_init);
4196 const string_lit_size = string_lit.getLength();4215 return transQualTypeInitializedStringLiteral(c, elem_ty, string_lit);
4197 const array_size = @intCast(usize, string_lit_size);
4198
4199 // incomplete array initialized with empty string, will be translated as [1]T{0}
4200 // see https://github.com/ziglang/zig/issues/8256
4201 if (array_size == 0) return Tag.array_type.create(c.arena, .{ .len = 1, .elem_type = elem_ty });
4202
4203 return Tag.null_sentinel_array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
4204 },4216 },
4205 .InitListExprClass => {4217 .InitListExprClass => {
4206 const init_expr = @ptrCast(*const clang.InitListExpr, decl_init);4218 const init_expr = @ptrCast(*const clang.InitListExpr, decl_init);
4207 const size = init_expr.getNumInits();4219 const size = init_expr.getNumInits();
4220
4221 if (init_expr.isStringLiteralInit()) {
4222 assert(size == 1);
4223 const string_lit = init_expr.getInit(0).castToStringLiteral().?;
4224 return transQualTypeInitializedStringLiteral(c, elem_ty, string_lit);
4225 }
4226
4208 return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });4227 return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });
4209 },4228 },
4210 else => {},4229 else => {},
src/zig_clang.cpp+16
...@@ -2382,6 +2382,12 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE...@@ -2382,6 +2382,12 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE
2382 return true;2382 return true;
2383}2383}
23842384
2385const ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self) {
2386 auto casted_self = reinterpret_cast<const clang::Expr *>(self);
2387 auto cast = clang::dyn_cast<const clang::StringLiteral>(casted_self);
2388 return reinterpret_cast<const ZigClangStringLiteral *>(cast);
2389}
2390
2385const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {2391const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {
2386 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);2392 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2387 const clang::Expr *result = casted->getInit(i);2393 const clang::Expr *result = casted->getInit(i);
...@@ -2394,6 +2400,16 @@ const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListEx...@@ -2394,6 +2400,16 @@ const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListEx
2394 return reinterpret_cast<const ZigClangExpr *>(result);2400 return reinterpret_cast<const ZigClangExpr *>(result);
2395}2401}
23962402
2403bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *self) {
2404 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2405 return casted->hasArrayFiller();
2406}
2407
2408bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *self) {
2409 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2410 return casted->isStringLiteralInit();
2411}
2412
2397const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) {2413const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) {
2398 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);2414 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2399 const clang::FieldDecl *result = casted->getInitializedFieldInUnion();2415 const clang::FieldDecl *result = casted->getInitializedFieldInUnion();
src/zig_clang.h+3
...@@ -1220,9 +1220,12 @@ ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsFloat(const struct ZigClangExpr *self,...@@ -1220,9 +1220,12 @@ ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsFloat(const struct ZigClangExpr *self,
1220 ZigClangAPFloat **result, const struct ZigClangASTContext *ctx);1220 ZigClangAPFloat **result, const struct ZigClangASTContext *ctx);
1221ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,1221ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,
1222 struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *);1222 struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *);
1223ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self);
12231224
1224ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);1225ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);
1225ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);1226ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);
1227ZIG_EXTERN_C bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *);
1228ZIG_EXTERN_C bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *);
1226ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);1229ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);
1227ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self);1230ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self);
12281231
test/translate_c.zig+6
...@@ -3956,4 +3956,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3956,4 +3956,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3956 \\ .name = "foo",3956 \\ .name = "foo",
3957 \\});3957 \\});
3958 });3958 });
3959
3960 cases.add("string array initializer",
3961 \\static const char foo[] = {"bar"};
3962 , &[_][]const u8{
3963 \\pub const foo: [3:0]u8 = "bar";
3964 });
3959}3965}