| author | |
| committer | |
| log | a8bd55e0853f7f80c9cd843ec54813425e4276bc |
| tree | 43c45d380722b2f9b32a650d0b4e30a8d1788ff3 |
| parent | c93e0d86187cb589d6726acd36f741f3d87a96be |
Resolves: #147433 files changed, 51 insertions(+), 1 deletions(-)
src/translate_c.zig+15-1| ... | @@ -784,9 +784,9 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co | ... | @@ -784,9 +784,9 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 784 | 784 | ||
| 785 | const qual_type = var_decl.getTypeSourceInfo_getType(); | 785 | const qual_type = var_decl.getTypeSourceInfo_getType(); |
| 786 | const storage_class = var_decl.getStorageClass(); | 786 | const storage_class = var_decl.getStorageClass(); |
| 787 | const is_const = qual_type.isConstQualified(); | ||
| 788 | const has_init = var_decl.hasInit(); | 787 | const has_init = var_decl.hasInit(); |
| 789 | const decl_init = var_decl.getInit(); | 788 | const decl_init = var_decl.getInit(); |
| 789 | var is_const = qual_type.isConstQualified(); | ||
| 790 | 790 | ||
| 791 | // In C extern variables with initializers behave like Zig exports. | 791 | // In C extern variables with initializers behave like Zig exports. |
| 792 | // extern int foo = 2; | 792 | // extern int foo = 2; |
| ... | @@ -843,6 +843,20 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co | ... | @@ -843,6 +843,20 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 843 | 843 | ||
| 844 | // std.mem.zeroes(T) | 844 | // std.mem.zeroes(T) |
| 845 | init_node = try Tag.std_mem_zeroes.create(c.arena, type_node); | 845 | init_node = try Tag.std_mem_zeroes.create(c.arena, type_node); |
| 846 | } else if (qual_type.getTypeClass() == .IncompleteArray) { | ||
| 847 | // Oh no, an extern array of unknown size! These are really fun because there's no | ||
| 848 | // direct equivalent in Zig. To translate correctly, we'll have to create a C-pointer | ||
| 849 | // to the data initialized via @extern. | ||
| 850 | |||
| 851 | const name_str = try std.fmt.allocPrint(c.arena, "\"{s}\"", .{var_name}); | ||
| 852 | init_node = try Tag.builtin_extern.create(c.arena, .{ | ||
| 853 | .type = type_node, | ||
| 854 | .name = try Tag.string_literal.create(c.arena, name_str), | ||
| 855 | }); | ||
| 856 | |||
| 857 | // Since this is really a pointer to the underlying data, we tweak a few properties. | ||
| 858 | is_extern = false; | ||
| 859 | is_const = true; | ||
| 846 | } | 860 | } |
| 847 | 861 | ||
| 848 | const linksection_string = blk: { | 862 | const linksection_string = blk: { |
src/translate_c/ast.zig+28| ... | @@ -158,6 +158,8 @@ pub const Node = extern union { | ... | @@ -158,6 +158,8 @@ pub const Node = extern union { |
| 158 | vector_zero_init, | 158 | vector_zero_init, |
| 159 | /// @shuffle(type, a, b, mask) | 159 | /// @shuffle(type, a, b, mask) |
| 160 | shuffle, | 160 | shuffle, |
| 161 | /// @extern(ty, .{ .name = n }) | ||
| 162 | builtin_extern, | ||
| 161 | 163 | ||
| 162 | /// @import("std").zig.c_translation.MacroArithmetic.<op>(lhs, rhs) | 164 | /// @import("std").zig.c_translation.MacroArithmetic.<op>(lhs, rhs) |
| 163 | macro_arithmetic, | 165 | macro_arithmetic, |
| ... | @@ -373,6 +375,7 @@ pub const Node = extern union { | ... | @@ -373,6 +375,7 @@ pub const Node = extern union { |
| 373 | .field_access => Payload.FieldAccess, | 375 | .field_access => Payload.FieldAccess, |
| 374 | .string_slice => Payload.StringSlice, | 376 | .string_slice => Payload.StringSlice, |
| 375 | .shuffle => Payload.Shuffle, | 377 | .shuffle => Payload.Shuffle, |
| 378 | .builtin_extern => Payload.Extern, | ||
| 376 | .macro_arithmetic => Payload.MacroArithmetic, | 379 | .macro_arithmetic => Payload.MacroArithmetic, |
| 377 | }; | 380 | }; |
| 378 | } | 381 | } |
| ... | @@ -718,6 +721,14 @@ pub const Payload = struct { | ... | @@ -718,6 +721,14 @@ pub const Payload = struct { |
| 718 | }, | 721 | }, |
| 719 | }; | 722 | }; |
| 720 | 723 | ||
| 724 | pub const Extern = struct { | ||
| 725 | base: Payload, | ||
| 726 | data: struct { | ||
| 727 | type: Node, | ||
| 728 | name: Node, | ||
| 729 | }, | ||
| 730 | }; | ||
| 731 | |||
| 721 | pub const MacroArithmetic = struct { | 732 | pub const MacroArithmetic = struct { |
| 722 | base: Payload, | 733 | base: Payload, |
| 723 | data: struct { | 734 | data: struct { |
| ... | @@ -1409,6 +1420,22 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1409,6 +1420,22 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1409 | payload.mask_vector, | 1420 | payload.mask_vector, |
| 1410 | }); | 1421 | }); |
| 1411 | }, | 1422 | }, |
| 1423 | .builtin_extern => { | ||
| 1424 | const payload = node.castTag(.builtin_extern).?.data; | ||
| 1425 | |||
| 1426 | var info_inits: [1]Payload.ContainerInitDot.Initializer = .{ | ||
| 1427 | .{ .name = "name", .value = payload.name }, | ||
| 1428 | }; | ||
| 1429 | var info_payload: Payload.ContainerInitDot = .{ | ||
| 1430 | .base = .{ .tag = .container_init_dot }, | ||
| 1431 | .data = &info_inits, | ||
| 1432 | }; | ||
| 1433 | |||
| 1434 | return renderBuiltinCall(c, "@extern", &.{ | ||
| 1435 | payload.type, | ||
| 1436 | .{ .ptr_otherwise = &info_payload.base }, | ||
| 1437 | }); | ||
| 1438 | }, | ||
| 1412 | .macro_arithmetic => { | 1439 | .macro_arithmetic => { |
| 1413 | const payload = node.castTag(.macro_arithmetic).?.data; | 1440 | const payload = node.castTag(.macro_arithmetic).?.data; |
| 1414 | const op = @tagName(payload.op); | 1441 | const op = @tagName(payload.op); |
| ... | @@ -2348,6 +2375,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -2348,6 +2375,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 2348 | .div_exact, | 2375 | .div_exact, |
| 2349 | .offset_of, | 2376 | .offset_of, |
| 2350 | .shuffle, | 2377 | .shuffle, |
| 2378 | .builtin_extern, | ||
| 2351 | .static_local_var, | 2379 | .static_local_var, |
| 2352 | .mut_str, | 2380 | .mut_str, |
| 2353 | .macro_arithmetic, | 2381 | .macro_arithmetic, |
test/translate_c.zig+8| ... | @@ -3948,4 +3948,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3948,4 +3948,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3948 | \\} | 3948 | \\} |
| 3949 | }); | 3949 | }); |
| 3950 | } | 3950 | } |
| 3951 | |||
| 3952 | cases.add("extern array of unknown length", | ||
| 3953 | \\extern int foo[]; | ||
| 3954 | , &[_][]const u8{ | ||
| 3955 | \\const foo: [*c]c_int = @extern([*c]c_int, .{ | ||
| 3956 | \\ .name = "foo", | ||
| 3957 | \\}); | ||
| 3958 | }); | ||
| 3951 | } | 3959 | } |