translate-c: use C pointer type everywhere

See #1059
This commit is contained in:
Andrew Kelley 2019-02-11 14:56:59 -05:00
parent 4a1b910e03
commit d9e01be973
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
6 changed files with 72 additions and 80 deletions

View File

@ -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();
}

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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;