| 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,6 +460,9 @@ pub const Expr = opaque { |
| 460 | 460 | ||
| 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 | }; |
| 464 | 467 | ||
| 465 | pub const FieldDecl = opaque { | 468 | pub 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; |
| 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 | 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; |
| 1058 | 1067 |
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 | } |
| 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 | 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); |
| 2702 | 2709 | ||
| ... | @@ -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; |
| 2716 | 2723 | ||
| 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 | } |
| 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 | /// Translate a qualtype for a variable with an initializer. This only matters | 4198 | /// 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. |
| 4181 | fn transQualTypeInitialized( | 4200 | fn 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 | } |
| 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 | const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) { | 2391 | const 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 | } |
| 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 | const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) { | 2413 | const 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); |
| 1221 | ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *, | 1221 | ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *, |
| 1222 | struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *); | 1222 | struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *); |
| 1223 | ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self); | ||
| 1223 | 1224 | ||
| 1224 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned); | 1225 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned); |
| 1225 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *); | 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 | ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *); | 1229 | ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *); |
| 1227 | ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self); | 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,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 | } |