| ... | ... | @@ -1085,6 +1085,26 @@ pub const DeclGen = struct { |
| 1085 | 1085 | const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(), .False); |
| 1086 | 1086 | return llvm_int.constIntToPtr(try self.llvmType(tv.ty)); |
| 1087 | 1087 | }, |
| 1088 | .field_ptr => { |
| 1089 | const field_ptr = tv.val.castTag(.field_ptr).?.data; |
| 1090 | const parent_ptr = try self.lowerParentPtr(field_ptr.container_ptr); |
| 1091 | const llvm_u32 = self.context.intType(32); |
| 1092 | const indices: [2]*const llvm.Value = .{ |
| 1093 | llvm_u32.constInt(0, .False), |
| 1094 | llvm_u32.constInt(field_ptr.field_index, .False), |
| 1095 | }; |
| 1096 | return parent_ptr.constInBoundsGEP(&indices, indices.len); |
| 1097 | }, |
| 1098 | .elem_ptr => { |
| 1099 | const elem_ptr = tv.val.castTag(.elem_ptr).?.data; |
| 1100 | const parent_ptr = try self.lowerParentPtr(elem_ptr.array_ptr); |
| 1101 | const llvm_usize = try self.llvmType(Type.usize); |
| 1102 | const indices: [2]*const llvm.Value = .{ |
| 1103 | llvm_usize.constInt(0, .False), |
| 1104 | llvm_usize.constInt(elem_ptr.index, .False), |
| 1105 | }; |
| 1106 | return parent_ptr.constInBoundsGEP(&indices, indices.len); |
| 1107 | }, |
| 1088 | 1108 | else => |tag| return self.todo("implement const of pointer type '{}' ({})", .{ tv.ty, tag }), |
| 1089 | 1109 | }, |
| 1090 | 1110 | .Array => switch (tv.val.tag()) { |
| ... | ... | @@ -1298,6 +1318,68 @@ pub const DeclGen = struct { |
| 1298 | 1318 | } |
| 1299 | 1319 | } |
| 1300 | 1320 | |
| 1321 | const ParentPtr = struct { |
| 1322 | ty: Type, |
| 1323 | llvm_ptr: *const llvm.Value, |
| 1324 | }; |
| 1325 | |
| 1326 | fn lowerParentPtrDecl( |
| 1327 | dg: *DeclGen, |
| 1328 | ptr_val: Value, |
| 1329 | decl: *Module.Decl, |
| 1330 | ) Error!ParentPtr { |
| 1331 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| 1332 | .base = .{ .tag = .single_mut_pointer }, |
| 1333 | .data = decl.ty, |
| 1334 | }; |
| 1335 | const ptr_ty = Type.initPayload(&ptr_ty_payload.base); |
| 1336 | const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl); |
| 1337 | return ParentPtr{ |
| 1338 | .llvm_ptr = llvm_ptr, |
| 1339 | .ty = decl.ty, |
| 1340 | }; |
| 1341 | } |
| 1342 | |
| 1343 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value) Error!*const llvm.Value { |
| 1344 | switch (ptr_val.tag()) { |
| 1345 | .decl_ref_mut => { |
| 1346 | const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl; |
| 1347 | return (try dg.lowerParentPtrDecl(ptr_val, decl)).llvm_ptr; |
| 1348 | }, |
| 1349 | .decl_ref => { |
| 1350 | const decl = ptr_val.castTag(.decl_ref).?.data; |
| 1351 | return (try dg.lowerParentPtrDecl(ptr_val, decl)).llvm_ptr; |
| 1352 | }, |
| 1353 | .variable => { |
| 1354 | const decl = ptr_val.castTag(.variable).?.data.owner_decl; |
| 1355 | return (try dg.lowerParentPtrDecl(ptr_val, decl)).llvm_ptr; |
| 1356 | }, |
| 1357 | .field_ptr => { |
| 1358 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; |
| 1359 | const parent_ptr = try dg.lowerParentPtr(field_ptr.container_ptr); |
| 1360 | const llvm_u32 = dg.context.intType(32); |
| 1361 | const indices: [2]*const llvm.Value = .{ |
| 1362 | llvm_u32.constInt(0, .False), |
| 1363 | llvm_u32.constInt(field_ptr.field_index, .False), |
| 1364 | }; |
| 1365 | return parent_ptr.constInBoundsGEP(&indices, indices.len); |
| 1366 | }, |
| 1367 | .elem_ptr => { |
| 1368 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; |
| 1369 | const parent_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr); |
| 1370 | const llvm_usize = try dg.llvmType(Type.usize); |
| 1371 | const indices: [2]*const llvm.Value = .{ |
| 1372 | llvm_usize.constInt(0, .False), |
| 1373 | llvm_usize.constInt(elem_ptr.index, .False), |
| 1374 | }; |
| 1375 | return parent_ptr.constInBoundsGEP(&indices, indices.len); |
| 1376 | }, |
| 1377 | .opt_payload_ptr => return dg.todo("implement lowerParentPtr for optional payload", .{}), |
| 1378 | .eu_payload_ptr => return dg.todo("implement lowerParentPtr for error union payload", .{}), |
| 1379 | else => unreachable, |
| 1380 | } |
| 1381 | } |
| 1382 | |
| 1301 | 1383 | fn lowerDeclRefValue( |
| 1302 | 1384 | self: *DeclGen, |
| 1303 | 1385 | tv: TypedValue, |
| ... | ... | @@ -1323,12 +1405,13 @@ pub const DeclGen = struct { |
| 1323 | 1405 | return self.context.constStruct(&fields, fields.len, .False); |
| 1324 | 1406 | } |
| 1325 | 1407 | |
| 1326 | | decl.alive = true; |
| 1327 | 1408 | const llvm_type = try self.llvmType(tv.ty); |
| 1328 | 1409 | if (!tv.ty.childType().hasCodeGenBits()) { |
| 1329 | 1410 | return self.lowerPtrToVoid(tv.ty); |
| 1330 | 1411 | } |
| 1331 | 1412 | |
| 1413 | decl.alive = true; |
| 1414 | |
| 1332 | 1415 | const llvm_val = if (decl.ty.zigTypeTag() == .Fn) |
| 1333 | 1416 | try self.resolveLlvmFunction(decl) |
| 1334 | 1417 | else |