stage2: more progress towards mutable local variables

* implement sema for runtime deref, store pointer, coerce_to_ptr_elem,
   and store
 * identifiers support being lvalues, except for decls is still TODO
 * codegen supports load, store, ref, alloc
 * introduce more MCValue union tags to support pointers
 * add load, ref, store typed IR instructions
 * add Type.isVolatilePtr
This commit is contained in:
Andrew Kelley
2020-07-28 17:27:44 -07:00
parent 11d38a7e52
commit 5ccee4c986
7 changed files with 377 additions and 70 deletions

View File

@@ -2151,7 +2151,8 @@ pub fn analyzeDeref(self: *Module, scope: *Scope, src: usize, ptr: *Inst, ptr_sr
});
}
return self.fail(scope, src, "TODO implement runtime deref", .{});
const b = try self.requireRuntimeBlock(scope, src);
return self.addUnOp(b, src, elem_ty, .load, ptr);
}
pub fn analyzeDeclRefByName(self: *Module, scope: *Scope, src: usize, decl_name: []const u8) InnerError!*Inst {
@@ -2504,6 +2505,22 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst
return self.fail(scope, inst.src, "TODO implement type coercion from {} to {}", .{ inst.ty, dest_type });
}
pub fn storePtr(self: *Module, scope: *Scope, src: usize, ptr: *Inst, uncasted_value: *Inst) !*Inst {
if (ptr.ty.isConstPtr())
return self.fail(scope, src, "cannot assign to constant", .{});
const elem_ty = ptr.ty.elemType();
const value = try self.coerce(scope, elem_ty, uncasted_value);
if (elem_ty.onePossibleValue())
return self.constVoid(scope, src);
// TODO handle comptime pointer writes
// TODO handle if the element type requires comptime
const b = try self.requireRuntimeBlock(scope, src);
return self.addBinOp(b, src, Type.initTag(.void), .store, ptr, value);
}
pub fn bitcast(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {
if (inst.value()) |val| {
// Keep the comptime Value representation; take the new type.
@@ -2780,3 +2797,9 @@ pub fn singleMutPtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type)
type_payload.* = .{ .pointee_type = elem_ty };
return Type.initPayload(&type_payload.base);
}
pub fn singleConstPtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type) error{OutOfMemory}!Type {
const type_payload = try scope.arena().create(Type.Payload.SingleConstPointer);
type_payload.* = .{ .pointee_type = elem_ty };
return Type.initPayload(&type_payload.base);
}