mirror of
https://github.com/ziglang/zig.git
synced 2026-01-17 12:55:16 +00:00
Merge pull request #17690
Sema: move remaining anon decls to new mechanism
This commit is contained in:
commit
ba817fae8f
@ -3556,7 +3556,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
|
||||
.gpa = gpa,
|
||||
.module = module,
|
||||
.error_msg = null,
|
||||
.decl_index = decl_index.toOptional(),
|
||||
.pass = .{ .decl = decl_index },
|
||||
.is_naked_fn = false,
|
||||
.fwd_decl = fwd_decl.toManaged(gpa),
|
||||
.ctypes = .{},
|
||||
|
||||
555
src/Sema.zig
555
src/Sema.zig
@ -5466,21 +5466,30 @@ fn addStrLitNoAlias(sema: *Sema, bytes: []const u8) CompileError!Air.Inst.Ref {
|
||||
.ty = array_ty.toIntern(),
|
||||
.storage = .{ .bytes = bytes },
|
||||
} });
|
||||
const ptr_ty = try sema.ptrType(.{
|
||||
.child = array_ty.toIntern(),
|
||||
return anonDeclRef(sema, val);
|
||||
}
|
||||
|
||||
fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
|
||||
return Air.internedToRef(try refValue(sema, val));
|
||||
}
|
||||
|
||||
fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
|
||||
const mod = sema.mod;
|
||||
const ptr_ty = (try sema.ptrType(.{
|
||||
.child = mod.intern_pool.typeOf(val),
|
||||
.flags = .{
|
||||
.alignment = .none,
|
||||
.is_const = true,
|
||||
.address_space = .generic,
|
||||
},
|
||||
});
|
||||
return Air.internedToRef((try mod.intern(.{ .ptr = .{
|
||||
.ty = ptr_ty.toIntern(),
|
||||
})).toIntern();
|
||||
return mod.intern(.{ .ptr = .{
|
||||
.ty = ptr_ty,
|
||||
.addr = .{ .anon_decl = .{
|
||||
.val = val,
|
||||
.orig_ty = ptr_ty.toIntern(),
|
||||
.orig_ty = ptr_ty,
|
||||
} },
|
||||
} })));
|
||||
} });
|
||||
}
|
||||
|
||||
fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
@ -10740,7 +10749,7 @@ const SwitchProngAnalysis = struct {
|
||||
return block.addStructFieldVal(spa.operand, field_index, field_ty);
|
||||
}
|
||||
} else if (capture_byref) {
|
||||
return sema.addConstantMaybeRef(block, operand_ty, item_val, true);
|
||||
return anonDeclRef(sema, item_val.toIntern());
|
||||
} else {
|
||||
return inline_case_capture;
|
||||
}
|
||||
@ -13765,10 +13774,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const coerced_elem_val = try sema.resolveConstValue(block, .unneeded, coerced_elem_val_inst, undefined);
|
||||
element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);
|
||||
}
|
||||
return sema.addConstantMaybeRef(block, result_ty, (try mod.intern(.{ .aggregate = .{
|
||||
return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{
|
||||
.ty = result_ty.toIntern(),
|
||||
.storage = .{ .elems = element_vals },
|
||||
} })).toValue(), ptr_addrspace != null);
|
||||
} }), ptr_addrspace != null);
|
||||
} else break :rs rhs_src;
|
||||
} else lhs_src;
|
||||
|
||||
@ -14034,7 +14043,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.storage = .{ .elems = element_vals },
|
||||
} });
|
||||
};
|
||||
return sema.addConstantMaybeRef(block, result_ty, val.toValue(), ptr_addrspace != null);
|
||||
return sema.addConstantMaybeRef(val, ptr_addrspace != null);
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, lhs_src);
|
||||
@ -16724,54 +16733,49 @@ fn zirBuiltinSrc(
|
||||
const src = LazySrcLoc.nodeOffset(extra.node);
|
||||
if (sema.func_index == .none) return sema.fail(block, src, "@src outside function", .{});
|
||||
const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);
|
||||
const ip = &mod.intern_pool;
|
||||
const gpa = sema.gpa;
|
||||
|
||||
const func_name_val = blk: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
// TODO: write something like getCoercedInts to avoid needing to dupe
|
||||
const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));
|
||||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
const func_name_val = v: {
|
||||
// This dupe prevents InternPool string pool memory from being reallocated
|
||||
// while a reference exists.
|
||||
const bytes = try sema.arena.dupe(u8, ip.stringToSlice(fn_owner_decl.name));
|
||||
const array_ty = try ip.get(gpa, .{ .array_type = .{
|
||||
.len = bytes.len,
|
||||
.sentinel = .zero_u8,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
break :blk try mod.intern(.{ .ptr = .{
|
||||
} });
|
||||
break :v try ip.get(gpa, .{ .ptr = .{
|
||||
.ty = .slice_const_u8_sentinel_0_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
.len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
|
||||
.addr = .{ .anon_decl = .{
|
||||
.orig_ty = .slice_const_u8_sentinel_0_type,
|
||||
.val = try ip.get(gpa, .{ .aggregate = .{
|
||||
.ty = array_ty,
|
||||
.storage = .{ .bytes = bytes },
|
||||
} }),
|
||||
} },
|
||||
} });
|
||||
};
|
||||
|
||||
const file_name_val = blk: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const file_name_val = v: {
|
||||
// The compiler must not call realpath anywhere.
|
||||
const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
|
||||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
const bytes = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
|
||||
const array_ty = try ip.get(gpa, .{ .array_type = .{
|
||||
.len = bytes.len,
|
||||
.sentinel = .zero_u8,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
break :blk try mod.intern(.{ .ptr = .{
|
||||
} });
|
||||
break :v try ip.get(gpa, .{ .ptr = .{
|
||||
.ty = .slice_const_u8_sentinel_0_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
.len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
|
||||
.addr = .{ .anon_decl = .{
|
||||
.orig_ty = .slice_const_u8_sentinel_0_type,
|
||||
.val = try ip.get(gpa, .{ .aggregate = .{
|
||||
.ty = array_ty,
|
||||
.storage = .{ .bytes = bytes },
|
||||
} }),
|
||||
} },
|
||||
} });
|
||||
};
|
||||
|
||||
@ -16818,10 +16822,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.val = .void_value,
|
||||
} }))),
|
||||
.Fn => {
|
||||
// TODO: look into memoizing this result.
|
||||
var params_anon_decl = try block.startAnonDecl();
|
||||
defer params_anon_decl.deinit();
|
||||
|
||||
const fn_info_decl_index = (try sema.namespaceLookup(
|
||||
block,
|
||||
src,
|
||||
@ -16878,23 +16878,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.len = param_vals.len,
|
||||
.child = param_info_ty.toIntern(),
|
||||
});
|
||||
const new_decl = try params_anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .elems = param_vals },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .elems = param_vals },
|
||||
} });
|
||||
const ptr_ty = (try sema.ptrType(.{
|
||||
.child = param_info_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern();
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = (try sema.ptrType(.{
|
||||
.child = param_info_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern(),
|
||||
.addr = .{ .decl = new_decl },
|
||||
.ty = ptr_ty,
|
||||
.addr = .{ .anon_decl = .{
|
||||
.orig_ty = ptr_ty,
|
||||
.val = new_decl_val,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -17035,7 +17035,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
// is_allowzero: bool,
|
||||
Value.makeBool(info.flags.is_allowzero).toIntern(),
|
||||
// sentinel: ?*const anyopaque,
|
||||
(try sema.optRefValue(block, info.child.toType(), switch (info.sentinel) {
|
||||
(try sema.optRefValue(switch (info.sentinel) {
|
||||
.none => null,
|
||||
else => info.sentinel.toValue(),
|
||||
})).toIntern(),
|
||||
@ -17070,7 +17070,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
// child: type,
|
||||
info.elem_type.toIntern(),
|
||||
// sentinel: ?*const anyopaque,
|
||||
(try sema.optRefValue(block, info.elem_type, info.sentinel)).toIntern(),
|
||||
(try sema.optRefValue(info.sentinel)).toIntern(),
|
||||
};
|
||||
return Air.internedToRef((try mod.intern(.{ .un = .{
|
||||
.ty = type_info_ty.toIntern(),
|
||||
@ -17139,9 +17139,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
} })));
|
||||
},
|
||||
.ErrorSet => {
|
||||
var fields_anon_decl = try block.startAnonDecl();
|
||||
defer fields_anon_decl.deinit();
|
||||
|
||||
// Get the Error type
|
||||
const error_field_ty = t: {
|
||||
const set_field_ty_decl_index = (try sema.namespaceLookup(
|
||||
@ -17170,23 +17167,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
// TODO: write something like getCoercedInts to avoid needing to dupe
|
||||
const name = try sema.arena.dupe(u8, ip.stringToSlice(names.get(ip)[i]));
|
||||
const name_val = v: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} });
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.addr = .{ .anon_decl = .{
|
||||
.val = new_decl_val,
|
||||
.orig_ty = .slice_const_u8_type,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -17219,17 +17213,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.len = vals.len,
|
||||
.child = error_field_ty.toIntern(),
|
||||
});
|
||||
const new_decl = try fields_anon_decl.finish(
|
||||
array_errors_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_errors_ty.toIntern(),
|
||||
.storage = .{ .elems = vals },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_errors_ty.toIntern(),
|
||||
.storage = .{ .elems = vals },
|
||||
} });
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = slice_errors_ty.toIntern(),
|
||||
.addr = .{ .decl = new_decl },
|
||||
.addr = .{ .anon_decl = .{
|
||||
.orig_ty = slice_errors_ty.toIntern(),
|
||||
.val = new_decl_val,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, vals.len)).toIntern(),
|
||||
} });
|
||||
} else .none;
|
||||
@ -17275,12 +17268,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
} })));
|
||||
},
|
||||
.Enum => {
|
||||
// TODO: look into memoizing this result.
|
||||
const is_exhaustive = Value.makeBool(ip.indexToKey(ty.toIntern()).enum_type.tag_mode != .nonexhaustive);
|
||||
|
||||
var fields_anon_decl = try block.startAnonDecl();
|
||||
defer fields_anon_decl.deinit();
|
||||
|
||||
const enum_field_ty = t: {
|
||||
const enum_field_ty_decl_index = (try sema.namespaceLookup(
|
||||
block,
|
||||
@ -17308,23 +17297,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
// TODO: write something like getCoercedInts to avoid needing to dupe
|
||||
const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names.get(ip)[i]));
|
||||
const name_val = v: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} });
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.addr = .{ .anon_decl = .{
|
||||
.val = new_decl_val,
|
||||
.orig_ty = .slice_const_u8_type,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -17346,23 +17332,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.len = enum_field_vals.len,
|
||||
.child = enum_field_ty.toIntern(),
|
||||
});
|
||||
const new_decl = try fields_anon_decl.finish(
|
||||
fields_array_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = fields_array_ty.toIntern(),
|
||||
.storage = .{ .elems = enum_field_vals },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = fields_array_ty.toIntern(),
|
||||
.storage = .{ .elems = enum_field_vals },
|
||||
} });
|
||||
const ptr_ty = (try sema.ptrType(.{
|
||||
.child = enum_field_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern();
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = (try sema.ptrType(.{
|
||||
.child = enum_field_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern(),
|
||||
.addr = .{ .decl = new_decl },
|
||||
.ty = ptr_ty,
|
||||
.addr = .{ .anon_decl = .{
|
||||
.val = new_decl_val,
|
||||
.orig_ty = ptr_ty,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -17402,11 +17388,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
} })));
|
||||
},
|
||||
.Union => {
|
||||
// TODO: look into memoizing this result.
|
||||
|
||||
var fields_anon_decl = try block.startAnonDecl();
|
||||
defer fields_anon_decl.deinit();
|
||||
|
||||
const type_union_ty = t: {
|
||||
const type_union_ty_decl_index = (try sema.namespaceLookup(
|
||||
block,
|
||||
@ -17444,23 +17425,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
// TODO: write something like getCoercedInts to avoid needing to dupe
|
||||
const name = try sema.arena.dupe(u8, ip.stringToSlice(union_obj.field_names.get(ip)[i]));
|
||||
const name_val = v: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} });
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.addr = .{ .anon_decl = .{
|
||||
.val = new_decl_val,
|
||||
.orig_ty = .slice_const_u8_type,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -17490,23 +17468,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.len = union_field_vals.len,
|
||||
.child = union_field_ty.toIntern(),
|
||||
});
|
||||
const new_decl = try fields_anon_decl.finish(
|
||||
array_fields_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_fields_ty.toIntern(),
|
||||
.storage = .{ .elems = union_field_vals },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_fields_ty.toIntern(),
|
||||
.storage = .{ .elems = union_field_vals },
|
||||
} });
|
||||
const ptr_ty = (try sema.ptrType(.{
|
||||
.child = union_field_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern();
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = (try sema.ptrType(.{
|
||||
.child = union_field_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern(),
|
||||
.addr = .{ .decl = new_decl },
|
||||
.ty = ptr_ty,
|
||||
.addr = .{ .anon_decl = .{
|
||||
.orig_ty = ptr_ty,
|
||||
.val = new_decl_val,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -17552,11 +17530,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
} })));
|
||||
},
|
||||
.Struct => {
|
||||
// TODO: look into memoizing this result.
|
||||
|
||||
var fields_anon_decl = try block.startAnonDecl();
|
||||
defer fields_anon_decl.deinit();
|
||||
|
||||
const type_struct_ty = t: {
|
||||
const type_struct_ty_decl_index = (try sema.namespaceLookup(
|
||||
block,
|
||||
@ -17596,8 +17569,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const field_ty = anon_struct_type.types.get(ip)[i];
|
||||
const field_val = anon_struct_type.values.get(ip)[i];
|
||||
const name_val = v: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
// TODO: write something like getCoercedInts to avoid needing to dupe
|
||||
const bytes = if (tuple.names.len != 0)
|
||||
// https://github.com/ziglang/zig/issues/15709
|
||||
@ -17608,17 +17579,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.len = bytes.len,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = bytes },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = bytes },
|
||||
} });
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.addr = .{ .anon_decl = .{
|
||||
.val = new_decl_val,
|
||||
.orig_ty = .slice_const_u8_type,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -17627,7 +17597,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
|
||||
const is_comptime = field_val != .none;
|
||||
const opt_default_val = if (is_comptime) field_val.toValue() else null;
|
||||
const default_val_ptr = try sema.optRefValue(block, field_ty.toType(), opt_default_val);
|
||||
const default_val_ptr = try sema.optRefValue(opt_default_val);
|
||||
const struct_field_fields = .{
|
||||
// name: []const u8,
|
||||
name_val,
|
||||
@ -17662,29 +17632,26 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const field_init = struct_type.fieldInit(ip, i);
|
||||
const field_is_comptime = struct_type.fieldIsComptime(ip, i);
|
||||
const name_val = v: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} });
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.addr = .{ .anon_decl = .{
|
||||
.val = new_decl_val,
|
||||
.orig_ty = .slice_const_u8_type,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
|
||||
const opt_default_val = if (field_init == .none) null else field_init.toValue();
|
||||
const default_val_ptr = try sema.optRefValue(block, field_ty, opt_default_val);
|
||||
const default_val_ptr = try sema.optRefValue(opt_default_val);
|
||||
const alignment = switch (struct_type.layout) {
|
||||
.Packed => .none,
|
||||
else => try sema.structFieldAlignment(
|
||||
@ -17718,23 +17685,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.len = struct_field_vals.len,
|
||||
.child = struct_field_ty.toIntern(),
|
||||
});
|
||||
const new_decl = try fields_anon_decl.finish(
|
||||
array_fields_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_fields_ty.toIntern(),
|
||||
.storage = .{ .elems = struct_field_vals },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_fields_ty.toIntern(),
|
||||
.storage = .{ .elems = struct_field_vals },
|
||||
} });
|
||||
const ptr_ty = (try sema.ptrType(.{
|
||||
.child = struct_field_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern();
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = (try sema.ptrType(.{
|
||||
.child = struct_field_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern(),
|
||||
.addr = .{ .decl = new_decl },
|
||||
.ty = ptr_ty,
|
||||
.addr = .{ .anon_decl = .{
|
||||
.orig_ty = ptr_ty,
|
||||
.val = new_decl_val,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -17786,8 +17753,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
} })));
|
||||
},
|
||||
.Opaque => {
|
||||
// TODO: look into memoizing this result.
|
||||
|
||||
const type_opaque_ty = t: {
|
||||
const type_opaque_ty_decl_index = (try sema.namespaceLookup(
|
||||
block,
|
||||
@ -17832,9 +17797,6 @@ fn typeInfoDecls(
|
||||
const mod = sema.mod;
|
||||
const gpa = sema.gpa;
|
||||
|
||||
var decls_anon_decl = try block.startAnonDecl();
|
||||
defer decls_anon_decl.deinit();
|
||||
|
||||
const declaration_ty = t: {
|
||||
const declaration_ty_decl_index = (try sema.namespaceLookup(
|
||||
block,
|
||||
@ -17864,23 +17826,23 @@ fn typeInfoDecls(
|
||||
.len = decl_vals.items.len,
|
||||
.child = declaration_ty.toIntern(),
|
||||
});
|
||||
const new_decl = try decls_anon_decl.finish(
|
||||
array_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_decl_ty.toIntern(),
|
||||
.storage = .{ .elems = decl_vals.items },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_decl_ty.toIntern(),
|
||||
.storage = .{ .elems = decl_vals.items },
|
||||
} });
|
||||
const ptr_ty = (try sema.ptrType(.{
|
||||
.child = declaration_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern();
|
||||
return try mod.intern(.{ .ptr = .{
|
||||
.ty = (try sema.ptrType(.{
|
||||
.child = declaration_ty.toIntern(),
|
||||
.flags = .{
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
},
|
||||
})).toIntern(),
|
||||
.addr = .{ .decl = new_decl },
|
||||
.ty = ptr_ty,
|
||||
.addr = .{ .anon_decl = .{
|
||||
.orig_ty = ptr_ty,
|
||||
.val = new_decl_val,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),
|
||||
} });
|
||||
}
|
||||
@ -17909,25 +17871,22 @@ fn typeInfoNamespaceDecls(
|
||||
}
|
||||
if (decl.kind != .named or !decl.is_pub) continue;
|
||||
const name_val = v: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
// TODO: write something like getCoercedInts to avoid needing to dupe
|
||||
const name = try sema.arena.dupe(u8, ip.stringToSlice(decl.name));
|
||||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
const new_decl_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = name },
|
||||
} });
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.addr = .{ .anon_decl = .{
|
||||
.orig_ty = .slice_const_u8_type,
|
||||
.val = new_decl_val,
|
||||
} },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
@ -19072,10 +19031,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
|
||||
|
||||
if (is_byref) {
|
||||
const init_val = (try sema.resolveValue(init_ref)).?;
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const decl = try anon_decl.finish(init_ty, init_val, .none);
|
||||
return sema.analyzeDeclRef(decl);
|
||||
return anonDeclRef(sema, init_val.toIntern());
|
||||
} else {
|
||||
return init_ref;
|
||||
}
|
||||
@ -19298,7 +19254,7 @@ fn zirStructInit(
|
||||
} })).toValue();
|
||||
const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);
|
||||
const final_val = (try sema.resolveValue(final_val_inst)).?;
|
||||
return sema.addConstantMaybeRef(block, resolved_ty, final_val, is_ref);
|
||||
return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
|
||||
}
|
||||
|
||||
if (try sema.typeRequiresComptime(resolved_ty)) {
|
||||
@ -19458,7 +19414,7 @@ fn finishStructInit(
|
||||
} });
|
||||
const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val), init_src);
|
||||
const final_val = (try sema.resolveValue(final_val_inst)).?;
|
||||
return sema.addConstantMaybeRef(block, result_ty, final_val, is_ref);
|
||||
return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
|
||||
};
|
||||
|
||||
if (try sema.typeRequiresComptime(struct_ty)) {
|
||||
@ -19611,7 +19567,7 @@ fn structInitAnon(
|
||||
.ty = tuple_ty,
|
||||
.storage = .{ .elems = values },
|
||||
} });
|
||||
return sema.addConstantMaybeRef(block, tuple_ty.toType(), tuple_val.toValue(), is_ref);
|
||||
return sema.addConstantMaybeRef(tuple_val, is_ref);
|
||||
};
|
||||
|
||||
sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
|
||||
@ -19777,7 +19733,8 @@ fn zirArrayInit(
|
||||
.storage = .{ .elems = elem_vals },
|
||||
} });
|
||||
const result_ref = try sema.coerce(block, result_ty, Air.internedToRef(arr_val), src);
|
||||
return sema.addConstantMaybeRef(block, result_ty, (try sema.resolveValue(result_ref)).?, is_ref);
|
||||
const result_val = (try sema.resolveValue(result_ref)).?;
|
||||
return sema.addConstantMaybeRef(result_val.toIntern(), is_ref);
|
||||
};
|
||||
|
||||
sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
|
||||
@ -19896,7 +19853,7 @@ fn arrayInitAnon(
|
||||
.ty = tuple_ty,
|
||||
.storage = .{ .elems = values },
|
||||
} });
|
||||
return sema.addConstantMaybeRef(block, tuple_ty.toType(), tuple_val.toValue(), is_ref);
|
||||
return sema.addConstantMaybeRef(tuple_val, is_ref);
|
||||
};
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, runtime_src);
|
||||
@ -19931,23 +19888,8 @@ fn arrayInitAnon(
|
||||
return block.addAggregateInit(tuple_ty.toType(), element_refs);
|
||||
}
|
||||
|
||||
fn addConstantMaybeRef(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
ty: Type,
|
||||
val: Value,
|
||||
is_ref: bool,
|
||||
) !Air.Inst.Ref {
|
||||
if (!is_ref) return Air.internedToRef(val.toIntern());
|
||||
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const decl = try anon_decl.finish(
|
||||
ty,
|
||||
val,
|
||||
.none, // default alignment
|
||||
);
|
||||
return sema.analyzeDeclRef(decl);
|
||||
fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {
|
||||
return if (is_ref) anonDeclRef(sema, val) else Air.internedToRef(val);
|
||||
}
|
||||
|
||||
fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
@ -21429,28 +21371,9 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
|
||||
const ty = try sema.resolveType(block, ty_src, inst_data.operand);
|
||||
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
|
||||
var bytes = std.ArrayList(u8).init(sema.arena);
|
||||
defer bytes.deinit();
|
||||
try ty.print(bytes.writer(), mod);
|
||||
|
||||
const decl_ty = try mod.arrayType(.{
|
||||
.len = bytes.items.len,
|
||||
.sentinel = .zero_u8,
|
||||
.child = .u8_type,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = decl_ty.toIntern(),
|
||||
.storage = .{ .bytes = bytes.items },
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
);
|
||||
|
||||
return sema.analyzeDeclRef(new_decl);
|
||||
return addStrLitNoAlias(sema, bytes.items);
|
||||
}
|
||||
|
||||
fn zirFrameType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
@ -26333,13 +26256,8 @@ fn fieldPtr(
|
||||
switch (inner_ty.zigTypeTag(mod)) {
|
||||
.Array => {
|
||||
if (ip.stringEqlSlice(field_name, "len")) {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
return sema.analyzeDeclRef(try anon_decl.finish(
|
||||
Type.usize,
|
||||
try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
|
||||
.none, // default alignment
|
||||
));
|
||||
const int_val = try mod.intValue(Type.usize, inner_ty.arrayLen(mod));
|
||||
return anonDeclRef(sema, int_val.toIntern());
|
||||
} else {
|
||||
return sema.fail(
|
||||
block,
|
||||
@ -26448,20 +26366,14 @@ fn fieldPtr(
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const error_set_type = if (!child_type.isAnyError(mod))
|
||||
child_type
|
||||
else
|
||||
try mod.singleErrorSetType(field_name);
|
||||
return sema.analyzeDeclRef(try anon_decl.finish(
|
||||
error_set_type,
|
||||
(try mod.intern(.{ .err = .{
|
||||
.ty = error_set_type.toIntern(),
|
||||
.name = field_name,
|
||||
} })).toValue(),
|
||||
.none, // default alignment
|
||||
));
|
||||
return anonDeclRef(sema, try mod.intern(.{ .err = .{
|
||||
.ty = error_set_type.toIntern(),
|
||||
.name = field_name,
|
||||
} }));
|
||||
},
|
||||
.Union => {
|
||||
if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
|
||||
@ -26473,13 +26385,8 @@ fn fieldPtr(
|
||||
if (child_type.unionTagType(mod)) |enum_ty| {
|
||||
if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
|
||||
const field_index_u32: u32 = @intCast(field_index);
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
return sema.analyzeDeclRef(try anon_decl.finish(
|
||||
enum_ty,
|
||||
try mod.enumValueFieldIndex(enum_ty, field_index_u32),
|
||||
.none, // default alignment
|
||||
));
|
||||
const idx_val = try mod.enumValueFieldIndex(enum_ty, field_index_u32);
|
||||
return anonDeclRef(sema, idx_val.toIntern());
|
||||
}
|
||||
}
|
||||
return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
|
||||
@ -26494,13 +26401,8 @@ fn fieldPtr(
|
||||
return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
|
||||
};
|
||||
const field_index_u32: u32 = @intCast(field_index);
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
return sema.analyzeDeclRef(try anon_decl.finish(
|
||||
child_type,
|
||||
try mod.enumValueFieldIndex(child_type, field_index_u32),
|
||||
.none, // default alignment
|
||||
));
|
||||
const idx_val = try mod.enumValueFieldIndex(child_type, field_index_u32);
|
||||
return anonDeclRef(sema, idx_val.toIntern());
|
||||
},
|
||||
.Struct, .Opaque => {
|
||||
if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
|
||||
@ -31669,31 +31571,13 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void
|
||||
};
|
||||
}
|
||||
|
||||
fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
|
||||
const mod = sema.mod;
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
const decl = try anon_decl.finish(
|
||||
ty,
|
||||
val,
|
||||
.none, // default alignment
|
||||
);
|
||||
try sema.maybeQueueFuncBodyAnalysis(decl);
|
||||
try mod.declareDeclDependency(sema.owner_decl_index, decl);
|
||||
const result = try mod.intern(.{ .ptr = .{
|
||||
.ty = (try mod.singleConstPtrType(ty)).toIntern(),
|
||||
.addr = .{ .decl = decl },
|
||||
} });
|
||||
return result.toValue();
|
||||
}
|
||||
|
||||
fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value {
|
||||
fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
|
||||
const mod = sema.mod;
|
||||
const ptr_anyopaque_ty = try mod.singleConstPtrType(Type.anyopaque);
|
||||
return (try mod.intern(.{ .opt = .{
|
||||
.ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
|
||||
.val = if (opt_val) |val| (try mod.getCoerced(
|
||||
try sema.refValue(block, ty, val),
|
||||
(try sema.refValue(val.toIntern())).toValue(),
|
||||
ptr_anyopaque_ty,
|
||||
)).toIntern() else .none,
|
||||
} })).toValue();
|
||||
@ -31755,15 +31639,8 @@ fn analyzeRef(
|
||||
switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
.extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),
|
||||
.func => |func| return sema.analyzeDeclRef(func.owner_decl),
|
||||
else => {},
|
||||
else => return anonDeclRef(sema, val.toIntern()),
|
||||
}
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
return sema.analyzeDeclRef(try anon_decl.finish(
|
||||
operand_ty,
|
||||
val,
|
||||
.none, // default alignment
|
||||
));
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, null);
|
||||
@ -36848,7 +36725,7 @@ fn analyzeComptimeAlloc(
|
||||
},
|
||||
});
|
||||
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
var anon_decl = try block.startAnonDecl(); // TODO: comptime value mutation without Decl
|
||||
defer anon_decl.deinit();
|
||||
|
||||
const decl_index = try anon_decl.finish(
|
||||
|
||||
@ -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);
|
||||
@ -1284,11 +1290,14 @@ pub const DeclGen = struct {
|
||||
var index: usize = 0;
|
||||
while (index < ai.len) : (index += 1) {
|
||||
const elem_val = try val.elemValue(mod, index);
|
||||
const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @as(u8, @intCast(elem_val.toUnsignedInt(mod)));
|
||||
const elem_val_u8: u8 = if (elem_val.isUndef(mod))
|
||||
undefPattern(u8)
|
||||
else
|
||||
@intCast(elem_val.toUnsignedInt(mod));
|
||||
try literal.writeChar(elem_val_u8);
|
||||
}
|
||||
if (ai.sentinel) |s| {
|
||||
const s_u8 = @as(u8, @intCast(s.toUnsignedInt(mod)));
|
||||
const s_u8: u8 = @intCast(s.toUnsignedInt(mod));
|
||||
if (s_u8 != 0) try literal.writeChar(s_u8);
|
||||
}
|
||||
try literal.end();
|
||||
@ -1298,7 +1307,10 @@ pub const DeclGen = struct {
|
||||
while (index < ai.len) : (index += 1) {
|
||||
if (index != 0) try writer.writeByte(',');
|
||||
const elem_val = try val.elemValue(mod, index);
|
||||
const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @as(u8, @intCast(elem_val.toUnsignedInt(mod)));
|
||||
const elem_val_u8: u8 = if (elem_val.isUndef(mod))
|
||||
undefPattern(u8)
|
||||
else
|
||||
@intCast(elem_val.toUnsignedInt(mod));
|
||||
try writer.print("'\\x{x}'", .{elem_val_u8});
|
||||
}
|
||||
if (ai.sentinel) |s| {
|
||||
@ -1566,18 +1578,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 +1602,7 @@ pub const DeclGen = struct {
|
||||
}
|
||||
|
||||
try renderTypeSuffix(
|
||||
dg.decl_index,
|
||||
dg.pass,
|
||||
store.*,
|
||||
mod,
|
||||
w,
|
||||
@ -1652,8 +1657,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 +1804,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 +2074,7 @@ fn renderTypeName(
|
||||
}
|
||||
}
|
||||
fn renderTypePrefix(
|
||||
decl: Decl.OptionalIndex,
|
||||
pass: DeclGen.Pass,
|
||||
store: CType.Store.Set,
|
||||
mod: *Module,
|
||||
w: anytype,
|
||||
@ -2128,7 +2132,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 +2156,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 +2169,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 +2199,7 @@ fn renderTypePrefix(
|
||||
.packed_struct,
|
||||
.packed_union,
|
||||
=> return renderTypePrefix(
|
||||
decl,
|
||||
pass,
|
||||
store,
|
||||
mod,
|
||||
w,
|
||||
@ -2214,7 +2212,7 @@ fn renderTypePrefix(
|
||||
.varargs_function,
|
||||
=> {
|
||||
const child_trailing = try renderTypePrefix(
|
||||
decl,
|
||||
pass,
|
||||
store,
|
||||
mod,
|
||||
w,
|
||||
@ -2241,7 +2239,7 @@ fn renderTypePrefix(
|
||||
return trailing;
|
||||
}
|
||||
fn renderTypeSuffix(
|
||||
decl: Decl.OptionalIndex,
|
||||
pass: DeclGen.Pass,
|
||||
store: CType.Store.Set,
|
||||
mod: *Module,
|
||||
w: anytype,
|
||||
@ -2295,7 +2293,7 @@ fn renderTypeSuffix(
|
||||
.pointer_volatile,
|
||||
.pointer_const_volatile,
|
||||
=> try renderTypeSuffix(
|
||||
decl,
|
||||
pass,
|
||||
store,
|
||||
mod,
|
||||
w,
|
||||
@ -2314,7 +2312,7 @@ fn renderTypeSuffix(
|
||||
|
||||
try w.print("[{}]", .{cty.cast(CType.Payload.Sequence).?.data.len});
|
||||
try renderTypeSuffix(
|
||||
decl,
|
||||
pass,
|
||||
store,
|
||||
mod,
|
||||
w,
|
||||
@ -2356,9 +2354,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 +2370,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 +2390,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 +2404,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 +2433,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 +2558,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 +2698,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 +2785,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 +2831,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 +2854,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 +2867,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 +7285,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;
|
||||
|
||||
@ -158,9 +158,7 @@ pub fn updateFunc(
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = module.declPtr(decl_index);
|
||||
const gop = try self.decl_table.getOrPut(gpa, decl_index);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
const ctypes = &gop.value_ptr.ctypes;
|
||||
const lazy_fns = &gop.value_ptr.lazy_fns;
|
||||
const fwd_decl = &self.fwd_decl_buf;
|
||||
@ -180,7 +178,7 @@ pub fn updateFunc(
|
||||
.gpa = gpa,
|
||||
.module = module,
|
||||
.error_msg = null,
|
||||
.decl_index = decl_index.toOptional(),
|
||||
.pass = .{ .decl = decl_index },
|
||||
.is_naked_fn = decl.ty.fnCallingConvention(module) == .Naked,
|
||||
.fwd_decl = fwd_decl.toManaged(gpa),
|
||||
.ctypes = ctypes.*,
|
||||
@ -235,7 +233,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
|
||||
.gpa = gpa,
|
||||
.module = module,
|
||||
.error_msg = null,
|
||||
.decl_index = .none,
|
||||
.pass = .{ .anon = anon_decl },
|
||||
.is_naked_fn = false,
|
||||
.fwd_decl = fwd_decl.toManaged(gpa),
|
||||
.ctypes = .{},
|
||||
@ -302,7 +300,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
|
||||
.gpa = gpa,
|
||||
.module = module,
|
||||
.error_msg = null,
|
||||
.decl_index = decl_index.toOptional(),
|
||||
.pass = .{ .decl = decl_index },
|
||||
.is_naked_fn = false,
|
||||
.fwd_decl = fwd_decl.toManaged(gpa),
|
||||
.ctypes = ctypes.*,
|
||||
@ -438,14 +436,14 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
|
||||
// We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes.
|
||||
// This ensures that every lazy CType.Index exactly matches the global CType.Index.
|
||||
assert(f.ctypes.count() == 0);
|
||||
try self.flushCTypes(&f, .none, f.lazy_ctypes);
|
||||
try self.flushCTypes(&f, .flush, f.lazy_ctypes);
|
||||
|
||||
for (self.anon_decls.values()) |decl_block| {
|
||||
try self.flushCTypes(&f, .none, decl_block.ctypes);
|
||||
for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| {
|
||||
try self.flushCTypes(&f, .{ .anon = anon_decl }, decl_block.ctypes);
|
||||
}
|
||||
|
||||
for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| {
|
||||
try self.flushCTypes(&f, decl_index.toOptional(), decl_block.ctypes);
|
||||
try self.flushCTypes(&f, .{ .decl = decl_index }, decl_block.ctypes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,7 +514,7 @@ const FlushDeclError = error{
|
||||
fn flushCTypes(
|
||||
self: *C,
|
||||
f: *Flush,
|
||||
decl_index: Module.Decl.OptionalIndex,
|
||||
pass: codegen.DeclGen.Pass,
|
||||
decl_ctypes: codegen.CType.Store,
|
||||
) FlushDeclError!void {
|
||||
const gpa = self.base.allocator;
|
||||
@ -591,7 +589,7 @@ fn flushCTypes(
|
||||
writer,
|
||||
global_ctypes.set,
|
||||
global_idx,
|
||||
decl_index,
|
||||
pass,
|
||||
decl_ctypes.set,
|
||||
decl_idx,
|
||||
gop.found_existing,
|
||||
@ -610,7 +608,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
|
||||
.gpa = gpa,
|
||||
.module = self.base.options.module.?,
|
||||
.error_msg = null,
|
||||
.decl_index = .none,
|
||||
.pass = .flush,
|
||||
.is_naked_fn = false,
|
||||
.fwd_decl = fwd_decl.toManaged(gpa),
|
||||
.ctypes = ctypes.*,
|
||||
@ -652,7 +650,7 @@ fn flushLazyFn(
|
||||
.gpa = gpa,
|
||||
.module = self.base.options.module.?,
|
||||
.error_msg = null,
|
||||
.decl_index = .none,
|
||||
.pass = .flush,
|
||||
.is_naked_fn = false,
|
||||
.fwd_decl = fwd_decl.toManaged(gpa),
|
||||
.ctypes = ctypes.*,
|
||||
|
||||
@ -1737,46 +1737,51 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
// This is basically the same as lowerUnnamedConst.
|
||||
// example:
|
||||
// const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
// const val = decl_val.toValue();
|
||||
// The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
|
||||
// It doesn't have an owner decl because it's just an unnamed constant that might
|
||||
// be used by more than one function, however, its address is being used so we need
|
||||
// to put it in some location.
|
||||
// ...
|
||||
pub fn lowerAnonDecl(
|
||||
self: *Coff,
|
||||
decl_val: InternPool.Index,
|
||||
explicit_alignment: InternPool.Alignment,
|
||||
src_loc: Module.SrcLoc,
|
||||
) !codegen.Result {
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
|
||||
const required_alignment = switch (decl_align) {
|
||||
const decl_alignment = switch (explicit_alignment) {
|
||||
.none => ty.abiAlignment(mod),
|
||||
else => decl_align,
|
||||
else => explicit_alignment,
|
||||
};
|
||||
if (!gop.found_existing or
|
||||
!required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value))
|
||||
{
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer gpa.free(name);
|
||||
const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) {
|
||||
else => {
|
||||
// TODO improve error message
|
||||
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
|
||||
@errorName(err),
|
||||
});
|
||||
return .{ .fail = em };
|
||||
},
|
||||
};
|
||||
const atom_index = switch (res) {
|
||||
.ok => |atom_index| atom_index,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
gop.value_ptr.* = atom_index;
|
||||
if (self.anon_decls.get(decl_val)) |atom_index| {
|
||||
const existing_addr = self.getAtom(atom_index).getSymbol(self).value;
|
||||
if (decl_alignment.check(existing_addr))
|
||||
return .ok;
|
||||
}
|
||||
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
var name_buf: [32]u8 = undefined;
|
||||
const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
|
||||
@intFromEnum(decl_val),
|
||||
}) catch unreachable;
|
||||
const res = self.lowerConst(
|
||||
name,
|
||||
tv,
|
||||
decl_alignment,
|
||||
self.rdata_section_index.?,
|
||||
src_loc,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return .{ .fail = try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"lowerAnonDecl failed with error: {s}",
|
||||
.{@errorName(e)},
|
||||
) },
|
||||
};
|
||||
const atom_index = switch (res) {
|
||||
.ok => |atom_index| atom_index,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
try self.anon_decls.put(gpa, decl_val, atom_index);
|
||||
return .ok;
|
||||
}
|
||||
|
||||
|
||||
@ -484,46 +484,51 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
// This is basically the same as lowerUnnamedConst.
|
||||
// example:
|
||||
// const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
// const val = decl_val.toValue();
|
||||
// The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
|
||||
// It doesn't have an owner decl because it's just an unnamed constant that might
|
||||
// be used by more than one function, however, its address is being used so we need
|
||||
// to put it in some location.
|
||||
// ...
|
||||
pub fn lowerAnonDecl(
|
||||
self: *Elf,
|
||||
decl_val: InternPool.Index,
|
||||
explicit_alignment: InternPool.Alignment,
|
||||
src_loc: Module.SrcLoc,
|
||||
) !codegen.Result {
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
|
||||
const required_alignment = switch (decl_align) {
|
||||
const decl_alignment = switch (explicit_alignment) {
|
||||
.none => ty.abiAlignment(mod),
|
||||
else => decl_align,
|
||||
else => explicit_alignment,
|
||||
};
|
||||
if (!gop.found_existing or
|
||||
required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt))
|
||||
{
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer gpa.free(name);
|
||||
const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {
|
||||
else => {
|
||||
// TODO improve error message
|
||||
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
|
||||
@errorName(err),
|
||||
});
|
||||
return .{ .fail = em };
|
||||
},
|
||||
};
|
||||
const sym_index = switch (res) {
|
||||
.ok => |sym_index| sym_index,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
gop.value_ptr.* = sym_index;
|
||||
if (self.anon_decls.get(decl_val)) |sym_index| {
|
||||
const existing_alignment = self.symbol(sym_index).atom(self).?.alignment;
|
||||
if (decl_alignment.order(existing_alignment).compare(.lte))
|
||||
return .ok;
|
||||
}
|
||||
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
var name_buf: [32]u8 = undefined;
|
||||
const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
|
||||
@intFromEnum(decl_val),
|
||||
}) catch unreachable;
|
||||
const res = self.lowerConst(
|
||||
name,
|
||||
tv,
|
||||
decl_alignment,
|
||||
self.zig_rodata_section_index.?,
|
||||
src_loc,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return .{ .fail = try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"unable to lower constant value: {s}",
|
||||
.{@errorName(e)},
|
||||
) },
|
||||
};
|
||||
const sym_index = switch (res) {
|
||||
.ok => |sym_index| sym_index,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
try self.anon_decls.put(gpa, decl_val, sym_index);
|
||||
return .ok;
|
||||
}
|
||||
|
||||
|
||||
@ -2866,46 +2866,51 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
// This is basically the same as lowerUnnamedConst.
|
||||
// example:
|
||||
// const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
// const val = decl_val.toValue();
|
||||
// The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
|
||||
// It doesn't have an owner decl because it's just an unnamed constant that might
|
||||
// be used by more than one function, however, its address is being used so we need
|
||||
// to put it in some location.
|
||||
// ...
|
||||
pub fn lowerAnonDecl(
|
||||
self: *MachO,
|
||||
decl_val: InternPool.Index,
|
||||
explicit_alignment: InternPool.Alignment,
|
||||
src_loc: Module.SrcLoc,
|
||||
) !codegen.Result {
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
|
||||
const required_alignment = switch (decl_align) {
|
||||
const decl_alignment = switch (explicit_alignment) {
|
||||
.none => ty.abiAlignment(mod),
|
||||
else => decl_align,
|
||||
else => explicit_alignment,
|
||||
};
|
||||
if (!gop.found_existing or
|
||||
!required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value))
|
||||
{
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer gpa.free(name);
|
||||
const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) {
|
||||
else => {
|
||||
// TODO improve error message
|
||||
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
|
||||
@errorName(err),
|
||||
});
|
||||
return .{ .fail = em };
|
||||
},
|
||||
};
|
||||
const atom_index = switch (res) {
|
||||
.ok => |atom_index| atom_index,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
gop.value_ptr.* = atom_index;
|
||||
if (self.anon_decls.get(decl_val)) |atom_index| {
|
||||
const existing_addr = self.getAtom(atom_index).getSymbol(self).n_value;
|
||||
if (decl_alignment.check(existing_addr))
|
||||
return .ok;
|
||||
}
|
||||
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
var name_buf: [32]u8 = undefined;
|
||||
const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
|
||||
@intFromEnum(decl_val),
|
||||
}) catch unreachable;
|
||||
const res = self.lowerConst(
|
||||
name,
|
||||
tv,
|
||||
decl_alignment,
|
||||
self.data_const_section_index.?,
|
||||
src_loc,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return .{ .fail = try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"unable to lower constant value: {s}",
|
||||
.{@errorName(e)},
|
||||
) },
|
||||
};
|
||||
const atom_index = switch (res) {
|
||||
.ok => |atom_index| atom_index,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
try self.anon_decls.put(gpa, decl_val, atom_index);
|
||||
return .ok;
|
||||
}
|
||||
|
||||
|
||||
@ -1702,27 +1702,34 @@ pub fn getDeclVAddr(
|
||||
return target_symbol_index;
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, decl_align: Alignment, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
pub fn lowerAnonDecl(
|
||||
wasm: *Wasm,
|
||||
decl_val: InternPool.Index,
|
||||
explicit_alignment: Alignment,
|
||||
src_loc: Module.SrcLoc,
|
||||
) !codegen.Result {
|
||||
const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);
|
||||
if (!gop.found_existing) {
|
||||
const mod = wasm.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };
|
||||
const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer wasm.base.allocator.free(name);
|
||||
var name_buf: [32]u8 = undefined;
|
||||
const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
|
||||
@intFromEnum(decl_val),
|
||||
}) catch unreachable;
|
||||
|
||||
switch (try wasm.lowerConst(name, tv, src_loc)) {
|
||||
.ok => |atom_index| gop.value_ptr.* = atom_index,
|
||||
.ok => |atom_index| wasm.anon_decls.values()[gop.index] = atom_index,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
}
|
||||
|
||||
const atom = wasm.getAtomPtr(gop.value_ptr.*);
|
||||
const atom = wasm.getAtomPtr(wasm.anon_decls.values()[gop.index]);
|
||||
atom.alignment = switch (atom.alignment) {
|
||||
.none => decl_align,
|
||||
else => switch (decl_align) {
|
||||
.none => explicit_alignment,
|
||||
else => switch (explicit_alignment) {
|
||||
.none => atom.alignment,
|
||||
else => atom.alignment.maxStrict(decl_align),
|
||||
else => atom.alignment.maxStrict(explicit_alignment),
|
||||
},
|
||||
};
|
||||
return .ok;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user