...
This commit is contained in:
@@ -2401,13 +2401,24 @@ pub const CodeGen = struct {
|
||||
if (ret_type.isStruct()) {
|
||||
const sname = self.resolveAlias(ret_type.struct_type);
|
||||
const info = try self.getStructInfo(sname);
|
||||
// If raw_val is already a struct value (not a pointer), return it directly
|
||||
if (c.LLVMGetTypeKind(c.LLVMTypeOf(raw_val)) != c.LLVMPointerTypeKind)
|
||||
return raw_val;
|
||||
return c.LLVMBuildLoad2(self.builder, info.llvm_type, raw_val, "retval");
|
||||
} else if (ret_type.isTuple()) {
|
||||
const llvm_ty = self.typeToLLVM(ret_type);
|
||||
if (c.LLVMGetTypeKind(c.LLVMTypeOf(raw_val)) != c.LLVMPointerTypeKind)
|
||||
return raw_val;
|
||||
return c.LLVMBuildLoad2(self.builder, llvm_ty, raw_val, "retval");
|
||||
} else if (ret_type.isUnion()) {
|
||||
const uname = ret_type.union_type;
|
||||
const resolved = self.resolveAlias(uname);
|
||||
// Try C-style (untagged) union first
|
||||
if (self.lookupUnionInfo(resolved)) |info| {
|
||||
if (c.LLVMGetTypeKind(c.LLVMTypeOf(raw_val)) != c.LLVMPointerTypeKind)
|
||||
return raw_val;
|
||||
return c.LLVMBuildLoad2(self.builder, info.llvm_type, raw_val, "retval");
|
||||
}
|
||||
const info = try self.getTaggedEnumInfo(resolved);
|
||||
return self.loadIfPointer(raw_val, info.llvm_type, "retval");
|
||||
} else {
|
||||
@@ -2811,7 +2822,10 @@ pub const CodeGen = struct {
|
||||
} else if (vd.value.?.data == .undef_literal) {
|
||||
self.storeUndef(info.llvm_type, alloca);
|
||||
} else {
|
||||
return self.emitErrorFmt("union '{s}' must be initialized with '---' or field assignment", .{uname});
|
||||
// Allow initialization from expression (e.g. function call returning union)
|
||||
var val = try self.genExpr(vd.value.?);
|
||||
val = self.loadIfPointer(val, info.llvm_type, "union_init");
|
||||
_ = c.LLVMBuildStore(self.builder, val, alloca);
|
||||
}
|
||||
|
||||
try self.registerVariable(vd.name, alloca, sx_ty);
|
||||
@@ -5530,6 +5544,20 @@ pub const CodeGen = struct {
|
||||
const slice_val = c.LLVMBuildLoad2(self.builder, self.getStringStructType(), loaded_ptr, "pslice_load");
|
||||
return self.extractFatPtrField(slice_val, fa.field, "*slice");
|
||||
}
|
||||
if (pointee_ty.isUnion()) {
|
||||
const uname = pointee_ty.union_type;
|
||||
if (self.lookupUnionInfo(uname)) |info| {
|
||||
if (self.findNameIndex(info.field_names, fa.field)) |fidx| {
|
||||
const field_ty = info.field_types[fidx];
|
||||
return self.loadTyped(field_ty, loaded_ptr, "punion_field");
|
||||
}
|
||||
if (info.promoted_fields.get(fa.field)) |pf| {
|
||||
const sinfo = try self.getStructInfo(pf.struct_name);
|
||||
return self.loadStructField(sinfo.llvm_type, loaded_ptr, @intCast(pf.field_index), self.typeToLLVM(pf.field_type));
|
||||
}
|
||||
return self.emitErrorFmt("no field '{s}' in union '{s}'", .{ fa.field, uname });
|
||||
}
|
||||
}
|
||||
return self.emitErrorFmt("no field '{s}' on pointer", .{fa.field});
|
||||
}
|
||||
if (entry.ty.isStruct()) {
|
||||
|
||||
Reference in New Issue
Block a user