aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig110
1 files changed, 55 insertions, 55 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 4a9258d155..061b574afc 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -522,7 +522,7 @@ pub const Object = struct {
pub const DeclGen = struct {
gpa: mem.Allocator,
module: *Module,
- decl_index: Decl.OptionalIndex,
+ pass: Pass,
is_naked_fn: bool,
/// This is a borrowed reference from `link.C`.
fwd_decl: std.ArrayList(u8),
@@ -533,10 +533,16 @@ pub const DeclGen = struct {
anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),
aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
+ pub const Pass = union(enum) {
+ decl: Decl.Index,
+ anon: InternPool.Index,
+ flush,
+ };
+
fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
@setCold(true);
const mod = dg.module;
- const decl_index = dg.decl_index.unwrap().?;
+ const decl_index = dg.pass.decl;
const decl = mod.declPtr(decl_index);
const src = LazySrcLoc.nodeOffset(0);
const src_loc = src.toSrcLoc(decl, mod);
@@ -1566,18 +1572,11 @@ pub const DeclGen = struct {
else => unreachable,
}
}
- if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold) try w.writeAll("zig_cold ");
+ if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold)
+ try w.writeAll("zig_cold ");
if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
- const trailing = try renderTypePrefix(
- dg.decl_index,
- store.*,
- mod,
- w,
- fn_cty_idx,
- .suffix,
- .{},
- );
+ const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{});
try w.print("{}", .{trailing});
if (toCallingConvention(fn_info.cc)) |call_conv| {
@@ -1597,7 +1596,7 @@ pub const DeclGen = struct {
}
try renderTypeSuffix(
- dg.decl_index,
+ dg.pass,
store.*,
mod,
w,
@@ -1652,8 +1651,8 @@ pub const DeclGen = struct {
fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {
const store = &dg.ctypes.set;
const mod = dg.module;
- _ = try renderTypePrefix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
- try renderTypeSuffix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
+ _ = try renderTypePrefix(dg.pass, store.*, mod, w, idx, .suffix, .{});
+ try renderTypeSuffix(dg.pass, store.*, mod, w, idx, .suffix, .{});
}
const IntCastContext = union(enum) {
@@ -1799,11 +1798,10 @@ pub const DeclGen = struct {
.gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
}
- const trailing =
- try renderTypePrefix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, qualifiers);
+ const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, cty_idx, .suffix, qualifiers);
try w.print("{}", .{trailing});
try dg.writeCValue(w, name);
- try renderTypeSuffix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, .{});
+ try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{});
}
fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
@@ -2070,7 +2068,7 @@ fn renderTypeName(
}
}
fn renderTypePrefix(
- decl: Decl.OptionalIndex,
+ pass: DeclGen.Pass,
store: CType.Store.Set,
mod: *Module,
w: anytype,
@@ -2128,7 +2126,7 @@ fn renderTypePrefix(
=> |tag| {
const child_idx = cty.cast(CType.Payload.Child).?.data;
const child_trailing = try renderTypePrefix(
- decl,
+ pass,
store,
mod,
w,
@@ -2152,15 +2150,8 @@ fn renderTypePrefix(
.vector,
=> {
const child_idx = cty.cast(CType.Payload.Sequence).?.data.elem_type;
- const child_trailing = try renderTypePrefix(
- decl,
- store,
- mod,
- w,
- child_idx,
- .suffix,
- qualifiers,
- );
+ const child_trailing =
+ try renderTypePrefix(pass, store, mod, w, child_idx, .suffix, qualifiers);
switch (parent_fix) {
.prefix => {
try w.print("{}(", .{child_trailing});
@@ -2172,10 +2163,11 @@ fn renderTypePrefix(
.fwd_anon_struct,
.fwd_anon_union,
- => if (decl.unwrap()) |decl_index|
- try w.print("anon__{d}_{d}", .{ @intFromEnum(decl_index), idx })
- else
- try renderTypeName(mod, w, idx, cty, ""),
+ => switch (pass) {
+ .decl => |decl_index| try w.print("decl__{d}_{d}", .{ @intFromEnum(decl_index), idx }),
+ .anon => |anon_decl| try w.print("anon__{d}_{d}", .{ @intFromEnum(anon_decl), idx }),
+ .flush => try renderTypeName(mod, w, idx, cty, ""),
+ },
.fwd_struct,
.fwd_union,
@@ -2201,7 +2193,7 @@ fn renderTypePrefix(
.packed_struct,
.packed_union,
=> return renderTypePrefix(
- decl,
+ pass,
store,
mod,
w,
@@ -2214,7 +2206,7 @@ fn renderTypePrefix(
.varargs_function,
=> {
const child_trailing = try renderTypePrefix(
- decl,
+ pass,
store,
mod,
w,
@@ -2241,7 +2233,7 @@ fn renderTypePrefix(
return trailing;
}
fn renderTypeSuffix(
- decl: Decl.OptionalIndex,
+ pass: DeclGen.Pass,
store: CType.Store.Set,
mod: *Module,
w: anytype,
@@ -2295,7 +2287,7 @@ fn renderTypeSuffix(
.pointer_volatile,
.pointer_const_volatile,
=> try renderTypeSuffix(
- decl,
+ pass,
store,
mod,
w,
@@ -2314,7 +2306,7 @@ fn renderTypeSuffix(
try w.print("[{}]", .{cty.cast(CType.Payload.Sequence).?.data.len});
try renderTypeSuffix(
- decl,
+ pass,
store,
mod,
w,
@@ -2356,9 +2348,9 @@ fn renderTypeSuffix(
if (need_comma) try w.writeAll(", ");
need_comma = true;
const trailing =
- try renderTypePrefix(decl, store, mod, w, param_type, .suffix, qualifiers);
+ try renderTypePrefix(pass, store, mod, w, param_type, .suffix, qualifiers);
if (qualifiers.contains(.@"const")) try w.print("{}a{d}", .{ trailing, param_i });
- try renderTypeSuffix(decl, store, mod, w, param_type, .suffix, .{});
+ try renderTypeSuffix(pass, store, mod, w, param_type, .suffix, .{});
}
switch (tag) {
.function => {},
@@ -2372,7 +2364,7 @@ fn renderTypeSuffix(
if (!need_comma) try w.writeAll("void");
try w.writeByte(')');
- try renderTypeSuffix(decl, store, mod, w, data.return_type, .suffix, .{});
+ try renderTypeSuffix(pass, store, mod, w, data.return_type, .suffix, .{});
},
}
}
@@ -2392,9 +2384,9 @@ fn renderAggregateFields(
.eq => {},
.gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),
}
- const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});
+ const trailing = try renderTypePrefix(.flush, store, mod, writer, field.type, .suffix, .{});
try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });
- try renderTypeSuffix(.none, store, mod, writer, field.type, .suffix, .{});
+ try renderTypeSuffix(.flush, store, mod, writer, field.type, .suffix, .{});
try writer.writeAll(";\n");
}
try writer.writeByteNTimes(' ', indent);
@@ -2406,18 +2398,18 @@ pub fn genTypeDecl(
writer: anytype,
global_store: CType.Store.Set,
global_idx: CType.Index,
- decl: Decl.OptionalIndex,
+ pass: DeclGen.Pass,
decl_store: CType.Store.Set,
decl_idx: CType.Index,
found_existing: bool,
) !void {
const global_cty = global_store.indexToCType(global_idx);
switch (global_cty.tag()) {
- .fwd_anon_struct => if (decl != .none) {
+ .fwd_anon_struct => if (pass != .flush) {
try writer.writeAll("typedef ");
- _ = try renderTypePrefix(.none, global_store, mod, writer, global_idx, .suffix, .{});
+ _ = try renderTypePrefix(.flush, global_store, mod, writer, global_idx, .suffix, .{});
try writer.writeByte(' ');
- _ = try renderTypePrefix(decl, decl_store, mod, writer, decl_idx, .suffix, .{});
+ _ = try renderTypePrefix(pass, decl_store, mod, writer, decl_idx, .suffix, .{});
try writer.writeAll(";\n");
},
@@ -2435,7 +2427,15 @@ pub fn genTypeDecl(
.fwd_union,
=> {
const owner_decl = global_cty.cast(CType.Payload.FwdDecl).?.data;
- _ = try renderTypePrefix(.none, global_store, mod, writer, global_idx, .suffix, .{});
+ _ = try renderTypePrefix(
+ .flush,
+ global_store,
+ mod,
+ writer,
+ global_idx,
+ .suffix,
+ .{},
+ );
try writer.writeAll("; // ");
try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer);
try writer.writeByte('\n');
@@ -2552,7 +2552,7 @@ fn genExports(o: *Object) !void {
const mod = o.dg.module;
const ip = &mod.intern_pool;
- const decl_index = o.dg.decl_index.unwrap().?;
+ const decl_index = o.dg.pass.decl;
const decl = mod.declPtr(decl_index);
const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
const fwd = o.dg.fwd_decl.writer();
@@ -2692,7 +2692,7 @@ pub fn genFunc(f: *Function) !void {
const o = &f.object;
const mod = o.dg.module;
const gpa = o.dg.gpa;
- const decl_index = o.dg.decl_index.unwrap().?;
+ const decl_index = o.dg.pass.decl;
const decl = mod.declPtr(decl_index);
const tv: TypedValue = .{
.ty = decl.ty,
@@ -2779,7 +2779,7 @@ pub fn genDecl(o: *Object) !void {
defer tracy.end();
const mod = o.dg.module;
- const decl_index = o.dg.decl_index.unwrap().?;
+ const decl_index = o.dg.pass.decl;
const decl = mod.declPtr(decl_index);
const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
@@ -2825,13 +2825,13 @@ pub fn genDeclValue(
alignment: Alignment,
link_section: InternPool.OptionalNullTerminatedString,
) !void {
+ const mod = o.dg.module;
const fwd_decl_writer = o.dg.fwd_decl.writer();
try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);
try fwd_decl_writer.writeAll(";\n");
- const mod = o.dg.module;
const w = o.writer();
if (!is_global) try w.writeAll("static ");
if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
@@ -2848,7 +2848,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
defer tracy.end();
const mod = dg.module;
- const decl_index = dg.decl_index.unwrap().?;
+ const decl_index = dg.pass.decl;
const decl = mod.declPtr(decl_index);
const tv: TypedValue = .{
.ty = decl.ty,
@@ -2861,7 +2861,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
const is_global = dg.declIsGlobal(tv);
if (is_global) {
try writer.writeAll("zig_extern ");
- try dg.renderFunctionSignature(writer, dg.decl_index.unwrap().?, .complete, .{ .export_index = 0 });
+ try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
try dg.fwd_decl.appendSlice(";\n");
}
},
@@ -7279,7 +7279,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const inst_ty = f.typeOfIndex(inst);
- const decl_index = f.object.dg.decl_index.unwrap().?;
+ const decl_index = f.object.dg.pass.decl;
const decl = mod.declPtr(decl_index);
const fn_cty = try f.typeToCType(decl.ty, .complete);
const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;