mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
translate-c: support brace-enclosed string initializers (c++20 9.4.2.1)
This commit is contained in:
parent
bc8e1e1de4
commit
42ee364e7b
@ -460,6 +460,9 @@ pub const Expr = opaque {
|
|||||||
|
|
||||||
pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;
|
pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;
|
||||||
extern fn ZigClangExpr_EvaluateAsConstantExpr(*const Expr, *ExprEvalResult, Expr_ConstantExprKind, *const ASTContext) bool;
|
extern fn ZigClangExpr_EvaluateAsConstantExpr(*const Expr, *ExprEvalResult, Expr_ConstantExprKind, *const ASTContext) bool;
|
||||||
|
|
||||||
|
pub const castToStringLiteral = ZigClangExpr_castToStringLiteral;
|
||||||
|
extern fn ZigClangExpr_castToStringLiteral(*const Expr) ?*const StringLiteral;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FieldDecl = opaque {
|
pub const FieldDecl = opaque {
|
||||||
@ -1053,6 +1056,12 @@ pub const InitListExpr = opaque {
|
|||||||
pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller;
|
pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller;
|
||||||
extern fn ZigClangInitListExpr_getArrayFiller(*const InitListExpr) *const Expr;
|
extern fn ZigClangInitListExpr_getArrayFiller(*const InitListExpr) *const Expr;
|
||||||
|
|
||||||
|
pub const hasArrayFiller = ZigClangInitListExpr_hasArrayFiller;
|
||||||
|
extern fn ZigClangInitListExpr_hasArrayFiller(*const InitListExpr) bool;
|
||||||
|
|
||||||
|
pub const isStringLiteralInit = ZigClangInitListExpr_isStringLiteralInit;
|
||||||
|
extern fn ZigClangInitListExpr_isStringLiteralInit(*const InitListExpr) bool;
|
||||||
|
|
||||||
pub const getNumInits = ZigClangInitListExpr_getNumInits;
|
pub const getNumInits = ZigClangInitListExpr_getNumInits;
|
||||||
extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint;
|
extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint;
|
||||||
|
|
||||||
|
|||||||
@ -2697,6 +2697,13 @@ fn transInitListExprArray(
|
|||||||
return Tag.empty_array.create(c.arena, child_type);
|
return Tag.empty_array.create(c.arena, child_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (expr.isStringLiteralInit()) {
|
||||||
|
assert(init_count == 1);
|
||||||
|
const init_expr = expr.getInit(0);
|
||||||
|
const string_literal = init_expr.castToStringLiteral().?;
|
||||||
|
return try transStringLiteral(c, scope, string_literal, .used);
|
||||||
|
}
|
||||||
|
|
||||||
const init_node = if (init_count != 0) blk: {
|
const init_node = if (init_count != 0) blk: {
|
||||||
const init_list = try c.arena.alloc(Node, init_count);
|
const init_list = try c.arena.alloc(Node, init_count);
|
||||||
|
|
||||||
@ -2714,6 +2721,7 @@ fn transInitListExprArray(
|
|||||||
break :blk init_node;
|
break :blk init_node;
|
||||||
} else null;
|
} else null;
|
||||||
|
|
||||||
|
assert(expr.hasArrayFiller());
|
||||||
const filler_val_expr = expr.getArrayFiller();
|
const filler_val_expr = expr.getArrayFiller();
|
||||||
const filler_node = try Tag.array_filler.create(c.arena, .{
|
const filler_node = try Tag.array_filler.create(c.arena, .{
|
||||||
.type = child_type,
|
.type = child_type,
|
||||||
@ -4176,6 +4184,17 @@ fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
|
|||||||
try c.global_scope.nodes.append(decl_node);
|
try c.global_scope.nodes.append(decl_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transQualTypeInitializedStringLiteral(c: *Context, elem_ty: Node, string_lit: *const clang.StringLiteral) TypeError!Node {
|
||||||
|
const string_lit_size = string_lit.getLength();
|
||||||
|
const array_size = @intCast(usize, string_lit_size);
|
||||||
|
|
||||||
|
// incomplete array initialized with empty string, will be translated as [1]T{0}
|
||||||
|
// see https://github.com/ziglang/zig/issues/8256
|
||||||
|
if (array_size == 0) return Tag.array_type.create(c.arena, .{ .len = 1, .elem_type = elem_ty });
|
||||||
|
|
||||||
|
return Tag.null_sentinel_array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
|
||||||
|
}
|
||||||
|
|
||||||
/// Translate a qualtype for a variable with an initializer. This only matters
|
/// Translate a qualtype for a variable with an initializer. This only matters
|
||||||
/// for incomplete arrays, since the initializer determines the size of the array.
|
/// for incomplete arrays, since the initializer determines the size of the array.
|
||||||
fn transQualTypeInitialized(
|
fn transQualTypeInitialized(
|
||||||
@ -4193,18 +4212,18 @@ fn transQualTypeInitialized(
|
|||||||
switch (decl_init.getStmtClass()) {
|
switch (decl_init.getStmtClass()) {
|
||||||
.StringLiteralClass => {
|
.StringLiteralClass => {
|
||||||
const string_lit = @ptrCast(*const clang.StringLiteral, decl_init);
|
const string_lit = @ptrCast(*const clang.StringLiteral, decl_init);
|
||||||
const string_lit_size = string_lit.getLength();
|
return transQualTypeInitializedStringLiteral(c, elem_ty, string_lit);
|
||||||
const array_size = @intCast(usize, string_lit_size);
|
|
||||||
|
|
||||||
// incomplete array initialized with empty string, will be translated as [1]T{0}
|
|
||||||
// see https://github.com/ziglang/zig/issues/8256
|
|
||||||
if (array_size == 0) return Tag.array_type.create(c.arena, .{ .len = 1, .elem_type = elem_ty });
|
|
||||||
|
|
||||||
return Tag.null_sentinel_array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
|
|
||||||
},
|
},
|
||||||
.InitListExprClass => {
|
.InitListExprClass => {
|
||||||
const init_expr = @ptrCast(*const clang.InitListExpr, decl_init);
|
const init_expr = @ptrCast(*const clang.InitListExpr, decl_init);
|
||||||
const size = init_expr.getNumInits();
|
const size = init_expr.getNumInits();
|
||||||
|
|
||||||
|
if (init_expr.isStringLiteralInit()) {
|
||||||
|
assert(size == 1);
|
||||||
|
const string_lit = init_expr.getInit(0).castToStringLiteral().?;
|
||||||
|
return transQualTypeInitializedStringLiteral(c, elem_ty, string_lit);
|
||||||
|
}
|
||||||
|
|
||||||
return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });
|
return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
|
|||||||
@ -2382,6 +2382,12 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self) {
|
||||||
|
auto casted_self = reinterpret_cast<const clang::Expr *>(self);
|
||||||
|
auto cast = clang::dyn_cast<const clang::StringLiteral>(casted_self);
|
||||||
|
return reinterpret_cast<const ZigClangStringLiteral *>(cast);
|
||||||
|
}
|
||||||
|
|
||||||
const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {
|
const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {
|
||||||
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
||||||
const clang::Expr *result = casted->getInit(i);
|
const clang::Expr *result = casted->getInit(i);
|
||||||
@ -2394,6 +2400,16 @@ const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListEx
|
|||||||
return reinterpret_cast<const ZigClangExpr *>(result);
|
return reinterpret_cast<const ZigClangExpr *>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *self) {
|
||||||
|
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
||||||
|
return casted->hasArrayFiller();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *self) {
|
||||||
|
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
||||||
|
return casted->isStringLiteralInit();
|
||||||
|
}
|
||||||
|
|
||||||
const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) {
|
const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) {
|
||||||
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
||||||
const clang::FieldDecl *result = casted->getInitializedFieldInUnion();
|
const clang::FieldDecl *result = casted->getInitializedFieldInUnion();
|
||||||
|
|||||||
@ -1220,9 +1220,12 @@ ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsFloat(const struct ZigClangExpr *self,
|
|||||||
ZigClangAPFloat **result, const struct ZigClangASTContext *ctx);
|
ZigClangAPFloat **result, const struct ZigClangASTContext *ctx);
|
||||||
ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,
|
ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,
|
||||||
struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *);
|
struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *);
|
||||||
|
ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self);
|
||||||
|
|
||||||
ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);
|
ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);
|
||||||
ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);
|
ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);
|
||||||
|
ZIG_EXTERN_C bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *);
|
||||||
|
ZIG_EXTERN_C bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *);
|
||||||
ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);
|
ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);
|
||||||
ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self);
|
ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self);
|
||||||
|
|
||||||
|
|||||||
@ -3956,4 +3956,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ .name = "foo",
|
\\ .name = "foo",
|
||||||
\\});
|
\\});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cases.add("string array initializer",
|
||||||
|
\\static const char foo[] = {"bar"};
|
||||||
|
, &[_][]const u8{
|
||||||
|
\\pub const foo: [3:0]u8 = "bar";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user