| author | |
| committer | |
| log | 42ee364e7b698822a69cba4cd2bda17868657e05 |
| tree | 4a69da6479fb97502dc83794e5d745e1fe3eb053 |
| parent | bc8e1e1de4a2f22c56528240d320f682f1ec4b69 |
5 files changed, 61 insertions(+), 8 deletions(-)
src/clang.zig+9| ... | ... | @@ -460,6 +460,9 @@ pub const Expr = opaque { |
| 460 | 460 | |
| 461 | 461 | pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr; |
| 462 | 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 | }; |
| 464 | 467 | |
| 465 | 468 | pub const FieldDecl = opaque { |
| ... | ... | @@ -1053,6 +1056,12 @@ pub const InitListExpr = opaque { |
| 1053 | 1056 | pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller; |
| 1054 | 1057 | extern fn ZigClangInitListExpr_getArrayFiller(*const InitListExpr) *const Expr; |
| 1055 | 1058 | |
| 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 | 1065 | pub const getNumInits = ZigClangInitListExpr_getNumInits; |
| 1057 | 1066 | extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint; |
| 1058 | 1067 |
src/translate_c.zig+27-8| ... | ... | @@ -2697,6 +2697,13 @@ fn transInitListExprArray( |
| 2697 | 2697 | return Tag.empty_array.create(c.arena, child_type); |
| 2698 | 2698 | } |
| 2699 | 2699 | |
| 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 | 2707 | const init_node = if (init_count != 0) blk: { |
| 2701 | 2708 | const init_list = try c.arena.alloc(Node, init_count); |
| 2702 | 2709 | |
| ... | ... | @@ -2714,6 +2721,7 @@ fn transInitListExprArray( |
| 2714 | 2721 | break :blk init_node; |
| 2715 | 2722 | } else null; |
| 2716 | 2723 | |
| 2724 | assert(expr.hasArrayFiller()); | |
| 2717 | 2725 | const filler_val_expr = expr.getArrayFiller(); |
| 2718 | 2726 | const filler_node = try Tag.array_filler.create(c.arena, .{ |
| 2719 | 2727 | .type = child_type, |
| ... | ... | @@ -4176,6 +4184,17 @@ fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void { |
| 4176 | 4184 | try c.global_scope.nodes.append(decl_node); |
| 4177 | 4185 | } |
| 4178 | 4186 | |
| 4187 | fn 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 | 4198 | /// Translate a qualtype for a variable with an initializer. This only matters |
| 4180 | 4199 | /// for incomplete arrays, since the initializer determines the size of the array. |
| 4181 | 4200 | fn transQualTypeInitialized( |
| ... | ... | @@ -4193,18 +4212,18 @@ fn transQualTypeInitialized( |
| 4193 | 4212 | switch (decl_init.getStmtClass()) { |
| 4194 | 4213 | .StringLiteralClass => { |
| 4195 | 4214 | const string_lit = @ptrCast(*const clang.StringLiteral, decl_init); |
| 4196 | const string_lit_size = string_lit.getLength(); | |
| 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 }); | |
| 4215 | return transQualTypeInitializedStringLiteral(c, elem_ty, string_lit); | |
| 4204 | 4216 | }, |
| 4205 | 4217 | .InitListExprClass => { |
| 4206 | 4218 | const init_expr = @ptrCast(*const clang.InitListExpr, decl_init); |
| 4207 | 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 | 4227 | return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty }); |
| 4209 | 4228 | }, |
| 4210 | 4229 | else => {}, |
src/zig_clang.cpp+16| ... | ... | @@ -2382,6 +2382,12 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE |
| 2382 | 2382 | return true; |
| 2383 | 2383 | } |
| 2384 | 2384 | |
| 2385 | const 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 | ||
| 2385 | 2391 | const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) { |
| 2386 | 2392 | auto casted = reinterpret_cast<const clang::InitListExpr *>(self); |
| 2387 | 2393 | const clang::Expr *result = casted->getInit(i); |
| ... | ... | @@ -2394,6 +2400,16 @@ const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListEx |
| 2394 | 2400 | return reinterpret_cast<const ZigClangExpr *>(result); |
| 2395 | 2401 | } |
| 2396 | 2402 | |
| 2403 | bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *self) { | |
| 2404 | auto casted = reinterpret_cast<const clang::InitListExpr *>(self); | |
| 2405 | return casted->hasArrayFiller(); | |
| 2406 | } | |
| 2407 | ||
| 2408 | bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *self) { | |
| 2409 | auto casted = reinterpret_cast<const clang::InitListExpr *>(self); | |
| 2410 | return casted->isStringLiteralInit(); | |
| 2411 | } | |
| 2412 | ||
| 2397 | 2413 | const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) { |
| 2398 | 2414 | auto casted = reinterpret_cast<const clang::InitListExpr *>(self); |
| 2399 | 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 | 1220 | ZigClangAPFloat **result, const struct ZigClangASTContext *ctx); |
| 1221 | 1221 | ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *, |
| 1222 | 1222 | struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *); |
| 1223 | ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self); | |
| 1223 | 1224 | |
| 1224 | 1225 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned); |
| 1225 | 1226 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *); |
| 1227 | ZIG_EXTERN_C bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *); | |
| 1228 | ZIG_EXTERN_C bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *); | |
| 1226 | 1229 | ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *); |
| 1227 | 1230 | ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self); |
| 1228 | 1231 |
test/translate_c.zig+6| ... | ... | @@ -3956,4 +3956,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3956 | 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 | } |