authorgravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2023-09-24 02:57:03-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-24 14:44:15-07:00
log127198e58cb3dcf2d2287124cf15a23a7d3a9c02
treecfbb741d5acdb26cdcf7184ba0a8e4391e761c69
parentfb6fff2561b5a56917e5efee4c374130189ab8b0

cbe: support more symbol attributes

implement codegen for: - decl weak linkage - decl aliases - fn decl weak linkage windows msvc: - `__declspec(selectany)` is not supported for functions - skip weak linkage for functions closes #17050

2 files changed, 61 insertions(+), 17 deletions(-)

lib/zig.h+3
...@@ -190,10 +190,13 @@ typedef char bool;...@@ -190,10 +190,13 @@ typedef char bool;
190190
191#if zig_has_attribute(weak) || defined(zig_gnuc)191#if zig_has_attribute(weak) || defined(zig_gnuc)
192#define zig_weak_linkage __attribute__((weak))192#define zig_weak_linkage __attribute__((weak))
193#define zig_weak_linkage_fn __attribute__((weak))
193#elif _MSC_VER194#elif _MSC_VER
194#define zig_weak_linkage __declspec(selectany)195#define zig_weak_linkage __declspec(selectany)
196#define zig_weak_linkage_fn
195#else197#else
196#define zig_weak_linkage zig_weak_linkage_unavailable198#define zig_weak_linkage zig_weak_linkage_unavailable
199#define zig_weak_linkage_fn zig_weak_linkage_unavailable
197#endif200#endif
198201
199#if zig_has_builtin(trap)202#if zig_has_builtin(trap)
src/codegen/c.zig+58-17
...@@ -1840,20 +1840,24 @@ pub const DeclGen = struct {...@@ -1840,20 +1840,24 @@ pub const DeclGen = struct {
18401840
1841 fn renderFwdDecl(dg: *DeclGen, decl_index: Decl.Index, variable: InternPool.Key.Variable) !void {1841 fn renderFwdDecl(dg: *DeclGen, decl_index: Decl.Index, variable: InternPool.Key.Variable) !void {
1842 const decl = dg.module.declPtr(decl_index);1842 const decl = dg.module.declPtr(decl_index);
1843 const fwd_decl_writer = dg.fwd_decl.writer();1843 const fwd = dg.fwd_decl.writer();
1844 const is_global = dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }) or variable.is_extern;1844 const is_global = dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }) or variable.is_extern;
1845 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");1845 try fwd.writeAll(if (is_global) "zig_extern " else "static ");
1846 if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal ");1846 const export_weak_linkage = if (dg.module.decl_exports.get(decl_index)) |exports|
1847 if (variable.is_weak_linkage) try fwd_decl_writer.writeAll("zig_weak_linkage ");1847 exports.items[0].opts.linkage == .Weak
1848 else
1849 false;
1850 if (variable.is_weak_linkage or export_weak_linkage) try fwd.writeAll("zig_weak_linkage ");
1851 if (variable.is_threadlocal) try fwd.writeAll("zig_threadlocal ");
1848 try dg.renderTypeAndName(1852 try dg.renderTypeAndName(
1849 fwd_decl_writer,1853 fwd,
1850 decl.ty,1854 decl.ty,
1851 .{ .decl = decl_index },1855 .{ .decl = decl_index },
1852 CQualifiers.init(.{ .@"const" = variable.is_const }),1856 CQualifiers.init(.{ .@"const" = variable.is_const }),
1853 decl.alignment,1857 decl.alignment,
1854 .complete,1858 .complete,
1855 );1859 );
1856 try fwd_decl_writer.writeAll(";\n");1860 try fwd.writeAll(";\n");
1857 }1861 }
18581862
1859 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void {1863 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void {
...@@ -2489,16 +2493,50 @@ fn genExports(o: *Object) !void {...@@ -2489,16 +2493,50 @@ fn genExports(o: *Object) !void {
24892493
2490 const mod = o.dg.module;2494 const mod = o.dg.module;
2491 const ip = &mod.intern_pool;2495 const ip = &mod.intern_pool;
2492 const fwd_decl_writer = o.dg.fwd_decl.writer();2496 const decl = o.dg.decl.?;
2493 if (mod.decl_exports.get(o.dg.decl_index.unwrap().?)) |exports| {2497 const decl_index = o.dg.decl_index.unwrap().?;
2494 for (exports.items[1..], 1..) |@"export", i| {2498 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
2495 try fwd_decl_writer.writeAll("zig_export(");2499 const fwd = o.dg.fwd_decl.writer();
2496 try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @as(u32, @intCast(i)) });2500
2497 try fwd_decl_writer.print(", {s}, {s});\n", .{2501 const exports = mod.decl_exports.get(decl_index) orelse return;
2498 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),2502 if (exports.items.len < 2) return;
2499 fmtStringLiteral(ip.stringToSlice(@"export".opts.name), null),2503
2500 });2504 switch (ip.indexToKey(tv.val.toIntern())) {
2501 }2505 .func => {
2506 for (exports.items[1..], 1..) |@"export", i| {
2507 try fwd.writeAll("zig_export(");
2508 if (exports.items[i].opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage_fn ");
2509 try o.dg.renderFunctionSignature(fwd, decl_index, .forward, .{ .export_index = @as(u32, @intCast(i)) });
2510 try fwd.print(", {s}, {s});\n", .{
2511 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
2512 fmtStringLiteral(ip.stringToSlice(@"export".opts.name), null),
2513 });
2514 }
2515 },
2516 .extern_func => {
2517 // TODO: when sema allows re-exporting extern decls
2518 unreachable;
2519 },
2520 .variable => |variable| {
2521 for (exports.items[1..], 1..) |@"export", i| {
2522 try fwd.writeAll("zig_export(");
2523 if (exports.items[i].opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage ");
2524 const alias = ip.stringToSlice(@"export".opts.name);
2525 try o.dg.renderTypeAndName(
2526 fwd,
2527 decl.ty,
2528 .{ .identifier = alias },
2529 CQualifiers.init(.{ .@"const" = variable.is_const }),
2530 decl.alignment,
2531 .complete,
2532 );
2533 try fwd.print(", {s}, {s});\n", .{
2534 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
2535 fmtStringLiteral(alias, null),
2536 });
2537 }
2538 },
2539 else => {},
2502 }2540 }
2503}2541}
25042542
...@@ -2593,6 +2631,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2593,6 +2631,7 @@ pub fn genFunc(f: *Function) !void {
2593 defer tracy.end();2631 defer tracy.end();
25942632
2595 const o = &f.object;2633 const o = &f.object;
2634 const mod = o.dg.module;
2596 const gpa = o.dg.gpa;2635 const gpa = o.dg.gpa;
2597 const decl_index = o.dg.decl_index.unwrap().?;2636 const decl_index = o.dg.decl_index.unwrap().?;
2598 const tv: TypedValue = .{2637 const tv: TypedValue = .{
...@@ -2606,6 +2645,8 @@ pub fn genFunc(f: *Function) !void {...@@ -2606,6 +2645,8 @@ pub fn genFunc(f: *Function) !void {
2606 const is_global = o.dg.declIsGlobal(tv);2645 const is_global = o.dg.declIsGlobal(tv);
2607 const fwd_decl_writer = o.dg.fwd_decl.writer();2646 const fwd_decl_writer = o.dg.fwd_decl.writer();
2608 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");2647 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2648 if (mod.decl_exports.get(decl_index)) |exports|
2649 if (exports.items[0].opts.linkage == .Weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn ");
2609 try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });2650 try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });
2610 try fwd_decl_writer.writeAll(";\n");2651 try fwd_decl_writer.writeAll(";\n");
2611 try genExports(o);2652 try genExports(o);
...@@ -2698,8 +2739,8 @@ pub fn genDecl(o: *Object) !void {...@@ -2698,8 +2739,8 @@ pub fn genDecl(o: *Object) !void {
2698 const is_global = o.dg.declIsGlobal(tv) or variable.is_extern;2739 const is_global = o.dg.declIsGlobal(tv) or variable.is_extern;
2699 const w = o.writer();2740 const w = o.writer();
2700 if (!is_global) try w.writeAll("static ");2741 if (!is_global) try w.writeAll("static ");
2701 if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
2702 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");2742 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
2743 if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
2703 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|2744 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2704 try w.print("zig_linksection(\"{s}\", ", .{s});2745 try w.print("zig_linksection(\"{s}\", ", .{s});
2705 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.alignment, .complete);2746 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.alignment, .complete);