| 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 | 784 | |
| 785 | 785 | const qual_type = var_decl.getTypeSourceInfo_getType(); |
| 786 | 786 | const storage_class = var_decl.getStorageClass(); |
| 787 | const is_const = qual_type.isConstQualified(); | |
| 788 | 787 | const has_init = var_decl.hasInit(); |
| 789 | 788 | const decl_init = var_decl.getInit(); |
| 789 | var is_const = qual_type.isConstQualified(); | |
| 790 | 790 | |
| 791 | 791 | // In C extern variables with initializers behave like Zig exports. |
| 792 | 792 | // extern int foo = 2; |
| ... | ... | @@ -843,6 +843,20 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 843 | 843 | |
| 844 | 844 | // std.mem.zeroes(T) |
| 845 | 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 | 862 | const linksection_string = blk: { |
src/translate_c/ast.zig+28| ... | ... | @@ -158,6 +158,8 @@ pub const Node = extern union { |
| 158 | 158 | vector_zero_init, |
| 159 | 159 | /// @shuffle(type, a, b, mask) |
| 160 | 160 | shuffle, |
| 161 | /// @extern(ty, .{ .name = n }) | |
| 162 | builtin_extern, | |
| 161 | 163 | |
| 162 | 164 | /// @import("std").zig.c_translation.MacroArithmetic.<op>(lhs, rhs) |
| 163 | 165 | macro_arithmetic, |
| ... | ... | @@ -373,6 +375,7 @@ pub const Node = extern union { |
| 373 | 375 | .field_access => Payload.FieldAccess, |
| 374 | 376 | .string_slice => Payload.StringSlice, |
| 375 | 377 | .shuffle => Payload.Shuffle, |
| 378 | .builtin_extern => Payload.Extern, | |
| 376 | 379 | .macro_arithmetic => Payload.MacroArithmetic, |
| 377 | 380 | }; |
| 378 | 381 | } |
| ... | ... | @@ -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 | 732 | pub const MacroArithmetic = struct { |
| 722 | 733 | base: Payload, |
| 723 | 734 | data: struct { |
| ... | ... | @@ -1409,6 +1420,22 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1409 | 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 | 1439 | .macro_arithmetic => { |
| 1413 | 1440 | const payload = node.castTag(.macro_arithmetic).?.data; |
| 1414 | 1441 | const op = @tagName(payload.op); |
| ... | ... | @@ -2348,6 +2375,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 2348 | 2375 | .div_exact, |
| 2349 | 2376 | .offset_of, |
| 2350 | 2377 | .shuffle, |
| 2378 | .builtin_extern, | |
| 2351 | 2379 | .static_local_var, |
| 2352 | 2380 | .mut_str, |
| 2353 | 2381 | .macro_arithmetic, |
test/translate_c.zig+8| ... | ... | @@ -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 | } |