1use crate::Builder;
2
3#[derive(Clone, Copy, Debug)]
5pub struct Pointer<B: Builder> {
6 pub ty: B::Type,
8 pub base: PointerBase<B>,
10}
11
12#[derive(Clone, Copy, Debug)]
14pub enum PointerBase<B: Builder> {
15 Address(B::Value),
17 StackSlot(B::StackSlot),
19}
20
21impl<B: Builder> Pointer<B> {
22 pub fn new_stack_slot(bcx: &mut B, ty: B::Type, name: &str) -> Self {
24 let slot = bcx.new_stack_slot_raw(ty, name);
25 Self { ty, base: PointerBase::StackSlot(slot) }
26 }
27
28 pub fn new_address(ty: B::Type, value: B::Value) -> Self {
30 Self { ty, base: PointerBase::Address(value) }
31 }
32
33 pub fn is_address(&self) -> bool {
35 matches!(self.base, PointerBase::Address(_))
36 }
37
38 pub fn is_stack_slot(&self) -> bool {
40 matches!(self.base, PointerBase::StackSlot(_))
41 }
42
43 pub fn into_address(self) -> Option<B::Value> {
45 match self.base {
46 PointerBase::Address(ptr) => Some(ptr),
47 PointerBase::StackSlot(_) => None,
48 }
49 }
50
51 pub fn into_stack_slot(self) -> Option<B::StackSlot> {
53 match self.base {
54 PointerBase::Address(_) => None,
55 PointerBase::StackSlot(slot) => Some(slot),
56 }
57 }
58
59 pub fn load(&self, bcx: &mut B, name: &str) -> B::Value {
61 match self.base {
62 PointerBase::Address(ptr) => bcx.load(self.ty, ptr, name),
63 PointerBase::StackSlot(slot) => bcx.stack_load(self.ty, slot, name),
64 }
65 }
66
67 pub fn store(&self, bcx: &mut B, value: B::Value) {
69 match self.base {
70 PointerBase::Address(ptr) => bcx.store(value, ptr),
71 PointerBase::StackSlot(slot) => bcx.stack_store(value, slot),
72 }
73 }
74
75 pub fn store_imm(&self, bcx: &mut B, value: i64) {
77 let value = bcx.iconst(self.ty, value);
78 self.store(bcx, value)
79 }
80
81 pub fn addr(&self, bcx: &mut B) -> B::Value {
83 match self.base {
84 PointerBase::Address(ptr) => ptr,
85 PointerBase::StackSlot(slot) => bcx.stack_addr(self.ty, slot),
86 }
87 }
88}