authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-20 02:23:09+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-20 03:44:02+02:00
log6329f4e47a78dc75b234e6d89c82fb3cff058fe1
treee1fec3554f167a4ed473a46e40b3575b19016ad7
parentd6f048c4565ee7b3d86c070c07dd555376a52ad2

stage2: union field value


2 files changed, 53 insertions(+), 24 deletions(-)

src/Sema.zig+26-14
...@@ -300,7 +300,7 @@ pub const Block = struct {...@@ -300,7 +300,7 @@ pub const Block = struct {
300 .ty = ty,300 .ty = ty,
301 .payload = try block.sema.addExtra(Air.StructField{301 .payload = try block.sema.addExtra(Air.StructField{
302 .struct_operand = struct_ptr,302 .struct_operand = struct_ptr,
303 .field_index = @intCast(u32, field_index),303 .field_index = field_index,
304 }),304 }),
305 } },305 } },
306 });306 });
...@@ -315,6 +315,24 @@ pub const Block = struct {...@@ -315,6 +315,24 @@ pub const Block = struct {
315 });315 });
316 }316 }
317317
318 pub fn addStructFieldVal(
319 block: *Block,
320 struct_val: Air.Inst.Ref,
321 field_index: u32,
322 field_ty: Type,
323 ) !Air.Inst.Ref {
324 return block.addInst(.{
325 .tag = .struct_field_val,
326 .data = .{ .ty_pl = .{
327 .ty = try block.sema.addType(field_ty),
328 .payload = try block.sema.addExtra(Air.StructField{
329 .struct_operand = struct_val,
330 .field_index = field_index,
331 }),
332 } },
333 });
334 }
335
318 pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref {336 pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref {
319 return Air.indexToRef(try block.addInstAsIndex(inst));337 return Air.indexToRef(try block.addInstAsIndex(inst));
320 }338 }
...@@ -11261,8 +11279,10 @@ fn structFieldVal(...@@ -11261,8 +11279,10 @@ fn structFieldVal(
11261 const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty);11279 const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty);
11262 const struct_obj = struct_ty.castTag(.@"struct").?.data;11280 const struct_obj = struct_ty.castTag(.@"struct").?.data;
1126311281
11264 const field_index = struct_obj.fields.getIndex(field_name) orelse11282 const field_index_big = struct_obj.fields.getIndex(field_name) orelse
11265 return sema.failWithBadFieldAccess(block, struct_obj, field_name_src, field_name);11283 return sema.failWithBadFieldAccess(block, struct_obj, field_name_src, field_name);
11284 const field_index = @intCast(u32, field_index_big);
11285
11266 const field = struct_obj.fields.values()[field_index];11286 const field = struct_obj.fields.values()[field_index];
1126711287
11268 if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| {11288 if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| {
...@@ -11273,16 +11293,7 @@ fn structFieldVal(...@@ -11273,16 +11293,7 @@ fn structFieldVal(
11273 }11293 }
1127411294
11275 try sema.requireRuntimeBlock(block, src);11295 try sema.requireRuntimeBlock(block, src);
11276 return block.addInst(.{11296 return block.addStructFieldVal(struct_byval, field_index, field.ty);
11277 .tag = .struct_field_val,
11278 .data = .{ .ty_pl = .{
11279 .ty = try sema.addType(field.ty),
11280 .payload = try sema.addExtra(Air.StructField{
11281 .struct_operand = struct_byval,
11282 .field_index = @intCast(u32, field_index),
11283 }),
11284 } },
11285 });
11286}11297}
1128711298
11288fn unionFieldPtr(11299fn unionFieldPtr(
...@@ -11341,8 +11352,9 @@ fn unionFieldVal(...@@ -11341,8 +11352,9 @@ fn unionFieldVal(
11341 const union_ty = try sema.resolveTypeFields(block, src, unresolved_union_ty);11352 const union_ty = try sema.resolveTypeFields(block, src, unresolved_union_ty);
11342 const union_obj = union_ty.cast(Type.Payload.Union).?.data;11353 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
1134311354
11344 const field_index = union_obj.fields.getIndex(field_name) orelse11355 const field_index_big = union_obj.fields.getIndex(field_name) orelse
11345 return sema.failWithBadUnionFieldAccess(block, union_obj, field_name_src, field_name);11356 return sema.failWithBadUnionFieldAccess(block, union_obj, field_name_src, field_name);
11357 const field_index = @intCast(u32, field_index_big);
1134611358
11347 const field = union_obj.fields.values()[field_index];11359 const field = union_obj.fields.values()[field_index];
1134811360
...@@ -11355,7 +11367,7 @@ fn unionFieldVal(...@@ -11355,7 +11367,7 @@ fn unionFieldVal(
11355 }11367 }
1135611368
11357 try sema.requireRuntimeBlock(block, src);11369 try sema.requireRuntimeBlock(block, src);
11358 return sema.fail(block, src, "TODO implement runtime union field access", .{});11370 return block.addStructFieldVal(union_byval, field_index, field.ty);
11359}11371}
1136011372
11361fn elemPtr(11373fn elemPtr(
src/codegen/llvm.zig+27-10
...@@ -2236,17 +2236,34 @@ pub const FuncGen = struct {...@@ -2236,17 +2236,34 @@ pub const FuncGen = struct {
2236 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;2236 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
2237 const struct_ty = self.air.typeOf(struct_field.struct_operand);2237 const struct_ty = self.air.typeOf(struct_field.struct_operand);
2238 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);2238 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
2239 const field_index = llvmFieldIndex(struct_ty, struct_field.field_index);2239 const field_index = struct_field.field_index;
2240 if (isByRef(struct_ty)) {2240 const field_ty = struct_ty.structFieldType(field_index);
2241 const field_ptr = self.builder.buildStructGEP(struct_llvm_val, field_index, "");2241 if (!field_ty.hasCodeGenBits()) {
2242 const field_ty = struct_ty.structFieldType(struct_field.field_index);2242 return null;
2243 if (isByRef(field_ty)) {2243 }
2244 return field_ptr;2244
2245 } else {2245 assert(isByRef(struct_ty));
2246 return self.builder.buildLoad(field_ptr, "");2246
2247 }2247 const field_ptr = switch (struct_ty.zigTypeTag()) {
2248 .Struct => blk: {
2249 const llvm_field_index = llvmFieldIndex(struct_ty, field_index);
2250 break :blk self.builder.buildStructGEP(struct_llvm_val, llvm_field_index, "");
2251 },
2252 .Union => blk: {
2253 const llvm_field_ty = try self.dg.llvmType(field_ty);
2254 const target = self.dg.module.getTarget();
2255 const layout = struct_ty.unionGetLayout(target);
2256 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
2257 const union_field_ptr = self.builder.buildStructGEP(struct_llvm_val, payload_index, "");
2258 break :blk self.builder.buildBitCast(union_field_ptr, llvm_field_ty.pointerType(0), "");
2259 },
2260 else => unreachable,
2261 };
2262
2263 if (isByRef(field_ty)) {
2264 return field_ptr;
2248 } else {2265 } else {
2249 return self.builder.buildExtractValue(struct_llvm_val, field_index, "");2266 return self.builder.buildLoad(field_ptr, "");
2250 }2267 }
2251 }2268 }
22522269