mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
parent
4a1b910e03
commit
d9e01be973
@ -6872,3 +6872,12 @@ Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_no
|
||||
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
const char *container_string(ContainerKind kind) {
|
||||
switch (kind) {
|
||||
case ContainerKindEnum: return "enum";
|
||||
case ContainerKindStruct: return "struct";
|
||||
case ContainerKindUnion: return "union";
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
@ -215,6 +215,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk);
|
||||
X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty);
|
||||
bool type_is_c_abi_int(CodeGen *g, ZigType *ty);
|
||||
bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id);
|
||||
const char *container_string(ContainerKind kind);
|
||||
|
||||
uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field);
|
||||
|
||||
|
||||
@ -136,13 +136,19 @@ static const char *thread_local_string(Token *tok) {
|
||||
return (tok == nullptr) ? "" : "threadlocal ";
|
||||
}
|
||||
|
||||
const char *container_string(ContainerKind kind) {
|
||||
switch (kind) {
|
||||
case ContainerKindEnum: return "enum";
|
||||
case ContainerKindStruct: return "struct";
|
||||
case ContainerKindUnion: return "union";
|
||||
static const char *token_to_ptr_len_str(Token *tok) {
|
||||
assert(tok != nullptr);
|
||||
switch (tok->id) {
|
||||
case TokenIdStar:
|
||||
case TokenIdStarStar:
|
||||
return "*";
|
||||
case TokenIdBracketStarBracket:
|
||||
return "[*]";
|
||||
case TokenIdBracketStarCBracket:
|
||||
return "[*c]";
|
||||
default:
|
||||
zig_unreachable();
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static const char *node_type_str(NodeType node_type) {
|
||||
@ -644,13 +650,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||
case NodeTypePointerType:
|
||||
{
|
||||
if (!grouped) fprintf(ar->f, "(");
|
||||
const char *star = "[*]";
|
||||
if (node->data.pointer_type.star_token != nullptr &&
|
||||
(node->data.pointer_type.star_token->id == TokenIdStar || node->data.pointer_type.star_token->id == TokenIdStarStar))
|
||||
{
|
||||
star = "*";
|
||||
}
|
||||
fprintf(ar->f, "%s", star);
|
||||
const char *ptr_len_str = token_to_ptr_len_str(node->data.pointer_type.star_token);
|
||||
fprintf(ar->f, "%s", ptr_len_str);
|
||||
if (node->data.pointer_type.align_expr != nullptr) {
|
||||
fprintf(ar->f, "align(");
|
||||
render_node_grouped(ar, node->data.pointer_type.align_expr);
|
||||
|
||||
@ -17,7 +17,4 @@ void ast_print(FILE *f, AstNode *node, int indent);
|
||||
|
||||
void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size);
|
||||
|
||||
const char *container_string(ContainerKind kind);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -291,11 +291,22 @@ static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNod
|
||||
node);
|
||||
}
|
||||
|
||||
static TokenId ptr_len_to_token_id(PtrLen ptr_len) {
|
||||
switch (ptr_len) {
|
||||
case PtrLenSingle:
|
||||
return TokenIdStar;
|
||||
case PtrLenUnknown:
|
||||
return TokenIdBracketStarBracket;
|
||||
case PtrLenC:
|
||||
return TokenIdBracketStarCBracket;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static AstNode *trans_create_node_ptr_type(Context *c, bool is_const, bool is_volatile, AstNode *child_node, PtrLen ptr_len) {
|
||||
AstNode *node = trans_create_node(c, NodeTypePointerType);
|
||||
node->data.pointer_type.star_token = allocate<ZigToken>(1);
|
||||
node->data.pointer_type.star_token->id = (ptr_len == PtrLenSingle) ? TokenIdStar: TokenIdBracketStarBracket;
|
||||
node->data.pointer_type.is_const = is_const;
|
||||
node->data.pointer_type.star_token->id = ptr_len_to_token_id(ptr_len);
|
||||
node->data.pointer_type.is_const = is_const;
|
||||
node->data.pointer_type.is_volatile = is_volatile;
|
||||
node->data.pointer_type.op_expr = child_node;
|
||||
@ -752,30 +763,6 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool type_is_opaque(Context *c, const Type *ty, const SourceLocation &source_loc) {
|
||||
switch (ty->getTypeClass()) {
|
||||
case Type::Builtin: {
|
||||
const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
|
||||
return builtin_ty->getKind() == BuiltinType::Void;
|
||||
}
|
||||
case Type::Record: {
|
||||
const RecordType *record_ty = static_cast<const RecordType*>(ty);
|
||||
return record_ty->getDecl()->getDefinition() == nullptr;
|
||||
}
|
||||
case Type::Elaborated: {
|
||||
const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
|
||||
return type_is_opaque(c, elaborated_ty->getNamedType().getTypePtr(), source_loc);
|
||||
}
|
||||
case Type::Typedef: {
|
||||
const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
|
||||
const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
|
||||
return type_is_opaque(c, typedef_decl->getUnderlyingType().getTypePtr(), source_loc);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {
|
||||
switch (ty->getTypeClass()) {
|
||||
case Type::Builtin:
|
||||
@ -925,11 +912,8 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
|
||||
return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
|
||||
}
|
||||
|
||||
PtrLen ptr_len = type_is_opaque(c, child_qt.getTypePtr(), source_loc) ? PtrLenSingle : PtrLenUnknown;
|
||||
|
||||
AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
|
||||
child_qt.isVolatileQualified(), child_node, ptr_len);
|
||||
return trans_create_node_prefix_op(c, PrefixOpOptional, pointer_node);
|
||||
return trans_create_node_ptr_type(c, child_qt.isConstQualified(),
|
||||
child_qt.isVolatileQualified(), child_node, PtrLenC);
|
||||
}
|
||||
case Type::Typedef:
|
||||
{
|
||||
@ -1113,7 +1097,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
|
||||
return nullptr;
|
||||
}
|
||||
AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
|
||||
child_qt.isVolatileQualified(), child_type_node, PtrLenUnknown);
|
||||
child_qt.isVolatileQualified(), child_type_node, PtrLenC);
|
||||
return pointer_node;
|
||||
}
|
||||
case Type::BlockPointer:
|
||||
@ -4568,7 +4552,7 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t
|
||||
} else if (first_tok->id == CTokIdAsterisk) {
|
||||
*tok_i += 1;
|
||||
|
||||
node = trans_create_node_ptr_type(c, false, false, node, PtrLenUnknown);
|
||||
node = trans_create_node_ptr_type(c, false, false, node, PtrLenC);
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -117,11 +117,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
,
|
||||
\\pub const struct_Foo = extern struct {
|
||||
\\ a: ?[*]Foo,
|
||||
\\ a: [*c]Foo,
|
||||
\\};
|
||||
\\pub const Foo = struct_Foo;
|
||||
\\pub const struct_Bar = extern struct {
|
||||
\\ a: ?[*]Foo,
|
||||
\\ a: [*c]Foo,
|
||||
\\};
|
||||
);
|
||||
|
||||
@ -202,7 +202,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("restrict -> noalias",
|
||||
\\void foo(void *restrict bar, void *restrict);
|
||||
,
|
||||
\\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void;
|
||||
\\pub extern fn foo(noalias bar: [*c]c_void, noalias arg1: [*c]c_void) void;
|
||||
);
|
||||
|
||||
cases.add("simple struct",
|
||||
@ -213,7 +213,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
,
|
||||
\\const struct_Foo = extern struct {
|
||||
\\ x: c_int,
|
||||
\\ y: ?[*]u8,
|
||||
\\ y: [*c]u8,
|
||||
\\};
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
@ -244,7 +244,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
,
|
||||
\\pub const BarB = enum_Bar.B;
|
||||
,
|
||||
\\pub extern fn func(a: ?[*]struct_Foo, b: ?[*](?[*]enum_Bar)) void;
|
||||
\\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void;
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
,
|
||||
@ -254,7 +254,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("constant size array",
|
||||
\\void func(int array[20]);
|
||||
,
|
||||
\\pub extern fn func(array: ?[*]c_int) void;
|
||||
\\pub extern fn func(array: [*c]c_int) void;
|
||||
);
|
||||
|
||||
cases.add("self referential struct with function pointer",
|
||||
@ -263,7 +263,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
,
|
||||
\\pub const struct_Foo = extern struct {
|
||||
\\ derp: ?extern fn(?[*]struct_Foo) void,
|
||||
\\ derp: ?extern fn([*c]struct_Foo) void,
|
||||
\\};
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
@ -275,7 +275,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
,
|
||||
\\pub const struct_Foo = @OpaqueType();
|
||||
,
|
||||
\\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
|
||||
\\pub extern fn some_func(foo: [*c]struct_Foo, x: c_int) [*c]struct_Foo;
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
);
|
||||
@ -322,11 +322,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
,
|
||||
\\pub const struct_Bar = extern struct {
|
||||
\\ next: ?[*]struct_Foo,
|
||||
\\ next: [*c]struct_Foo,
|
||||
\\};
|
||||
,
|
||||
\\pub const struct_Foo = extern struct {
|
||||
\\ next: ?[*]struct_Bar,
|
||||
\\ next: [*c]struct_Bar,
|
||||
\\};
|
||||
);
|
||||
|
||||
@ -336,7 +336,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
,
|
||||
\\pub const Foo = c_void;
|
||||
,
|
||||
\\pub extern fn fun(a: ?*Foo) Foo;
|
||||
\\pub extern fn fun(a: [*c]Foo) Foo;
|
||||
);
|
||||
|
||||
cases.add("generate inline func for #define global extern fn",
|
||||
@ -608,7 +608,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return 6;
|
||||
\\}
|
||||
,
|
||||
\\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\pub export fn and_or_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
|
||||
\\ if ((a != 0) and (b != 0)) return 0;
|
||||
\\ if ((b != 0) and (c != null)) return 1;
|
||||
\\ if ((a != 0) and (c != null)) return 2;
|
||||
@ -710,7 +710,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const struct_Foo = extern struct {
|
||||
\\ field: c_int,
|
||||
\\};
|
||||
\\pub export fn read_field(foo: ?[*]struct_Foo) c_int {
|
||||
\\pub export fn read_field(foo: [*c]struct_Foo) c_int {
|
||||
\\ return foo.?.field;
|
||||
\\}
|
||||
);
|
||||
@ -756,8 +756,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return x;
|
||||
\\}
|
||||
,
|
||||
\\pub export fn foo(x: ?[*]c_ushort) ?*c_void {
|
||||
\\ return @ptrCast(?*c_void, x);
|
||||
\\pub export fn foo(x: [*c]c_ushort) [*c]c_void {
|
||||
\\ return @ptrCast([*c]c_void, x);
|
||||
\\}
|
||||
);
|
||||
|
||||
@ -777,7 +777,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return 0;
|
||||
\\}
|
||||
,
|
||||
\\pub export fn foo() ?[*]c_int {
|
||||
\\pub export fn foo() [*c]c_int {
|
||||
\\ return null;
|
||||
\\}
|
||||
);
|
||||
@ -1086,7 +1086,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ *x = 1;
|
||||
\\}
|
||||
,
|
||||
\\pub export fn foo(x: ?[*]c_int) void {
|
||||
\\pub export fn foo(x: [*c]c_int) void {
|
||||
\\ x.?.* = 1;
|
||||
\\}
|
||||
);
|
||||
@ -1114,7 +1114,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
,
|
||||
\\pub fn foo() c_int {
|
||||
\\ var x: c_int = 1234;
|
||||
\\ var ptr: ?[*]c_int = &x;
|
||||
\\ var ptr: [*c]c_int = &x;
|
||||
\\ return ptr.?.*;
|
||||
\\}
|
||||
);
|
||||
@ -1124,7 +1124,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return "bar";
|
||||
\\}
|
||||
,
|
||||
\\pub fn foo() ?[*]const u8 {
|
||||
\\pub fn foo() [*c]const u8 {
|
||||
\\ return c"bar";
|
||||
\\}
|
||||
);
|
||||
@ -1253,8 +1253,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return (float *)a;
|
||||
\\}
|
||||
,
|
||||
\\fn ptrcast(a: ?[*]c_int) ?[*]f32 {
|
||||
\\ return @ptrCast(?[*]f32, a);
|
||||
\\fn ptrcast(a: [*c]c_int) [*c]f32 {
|
||||
\\ return @ptrCast([*c]f32, a);
|
||||
\\}
|
||||
);
|
||||
|
||||
@ -1276,7 +1276,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return !c;
|
||||
\\}
|
||||
,
|
||||
\\pub fn foo(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\pub fn foo(a: c_int, b: f32, c: [*c]c_void) c_int {
|
||||
\\ return !(a == 0);
|
||||
\\ return !(a != 0);
|
||||
\\ return !(b != 0);
|
||||
@ -1297,7 +1297,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("const ptr initializer",
|
||||
\\static const char *v0 = "0.0.0";
|
||||
,
|
||||
\\pub var v0: ?[*]const u8 = c"0.0.0";
|
||||
\\pub var v0: [*c]const u8 = c"0.0.0";
|
||||
);
|
||||
|
||||
cases.add("static incomplete array inside function",
|
||||
@ -1306,17 +1306,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
,
|
||||
\\pub fn foo() void {
|
||||
\\ const v2: [*]const u8 = c"2.2.2";
|
||||
\\ const v2: [*c]const u8 = c"2.2.2";
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.add("macro pointer cast",
|
||||
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
|
||||
,
|
||||
\\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*]NRF_GPIO_Type)(NRF_GPIO_BASE);
|
||||
\\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*c]NRF_GPIO_Type)(NRF_GPIO_BASE);
|
||||
);
|
||||
|
||||
cases.add("if on none bool",
|
||||
cases.add("if on non-bool",
|
||||
\\enum SomeEnum { A, B, C };
|
||||
\\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
|
||||
\\ if (a) return 0;
|
||||
@ -1334,7 +1334,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ B,
|
||||
\\ C,
|
||||
\\};
|
||||
\\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
|
||||
\\pub fn if_none_bool(a: c_int, b: f32, c: [*c]c_void, d: enum_SomeEnum) c_int {
|
||||
\\ if (a != 0) return 0;
|
||||
\\ if (b != 0) return 1;
|
||||
\\ if (c != null) return 2;
|
||||
@ -1343,7 +1343,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.add("while on none bool",
|
||||
cases.add("while on non-bool",
|
||||
\\int while_none_bool(int a, float b, void *c) {
|
||||
\\ while (a) return 0;
|
||||
\\ while (b) return 1;
|
||||
@ -1351,7 +1351,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return 3;
|
||||
\\}
|
||||
,
|
||||
\\pub fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\pub fn while_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
|
||||
\\ while (a != 0) return 0;
|
||||
\\ while (b != 0) return 1;
|
||||
\\ while (c != null) return 2;
|
||||
@ -1359,7 +1359,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.add("for on none bool",
|
||||
cases.add("for on non-bool",
|
||||
\\int for_none_bool(int a, float b, void *c) {
|
||||
\\ for (;a;) return 0;
|
||||
\\ for (;b;) return 1;
|
||||
@ -1367,7 +1367,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return 3;
|
||||
\\}
|
||||
,
|
||||
\\pub fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\pub fn for_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
|
||||
\\ while (a != 0) return 0;
|
||||
\\ while (b != 0) return 1;
|
||||
\\ while (c != null) return 2;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user