duskphantom_middle/ir/
global_variable.rs

1// Copyright 2024 Duskphantom Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// SPDX-License-Identifier: Apache-2.0
16
17use std::ops::{Deref, DerefMut};
18
19use super::*;
20
21#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
22pub struct GlobalPtr(ObjPtr<GlobalVariable>);
23impl Display for GlobalPtr {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        write!(f, "@{}", self.0.name)
26    }
27}
28impl Deref for GlobalPtr {
29    type Target = GlobalVariable;
30    fn deref(&self) -> &Self::Target {
31        self.0.as_ref()
32    }
33}
34impl DerefMut for GlobalPtr {
35    fn deref_mut(&mut self) -> &mut Self::Target {
36        self.0.as_mut()
37    }
38}
39impl AsRef<GlobalVariable> for GlobalPtr {
40    fn as_ref(&self) -> &GlobalVariable {
41        self.0.as_ref()
42    }
43}
44impl From<ObjPtr<GlobalVariable>> for GlobalPtr {
45    fn from(ptr: ObjPtr<GlobalVariable>) -> Self {
46        Self(ptr)
47    }
48}
49
50pub struct GlobalVariable {
51    pub name: String,
52    pub value_type: ValueType,
53    /// True if the global variable is a global variable, false if it is a global constant.
54    pub variable_or_constant: bool,
55    pub initializer: Constant,
56    user: Vec<InstPtr>,
57}
58
59impl Display for GlobalVariable {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        write!(f, "@{}", self.name)
62    }
63}
64
65impl GlobalVariable {
66    pub fn new(
67        name: String,
68        value_type: ValueType,
69        variable_or_constant: bool,
70        initializer: Constant,
71    ) -> Self {
72        Self {
73            name,
74            value_type,
75            variable_or_constant,
76            initializer,
77            user: Vec::new(),
78        }
79    }
80
81    pub fn gen_llvm_ir(&self) -> String {
82        format!(
83            "{} = dso_local {} {} {}\n",
84            self,
85            if self.variable_or_constant {
86                "global"
87            } else {
88                "constant"
89            },
90            self.value_type,
91            self.initializer,
92        )
93    }
94
95    pub fn get_user(&self) -> &[InstPtr] {
96        &self.user
97    }
98    pub fn get_user_mut(&mut self) -> &mut Vec<InstPtr> {
99        &mut self.user
100    }
101    /// # Safety
102    /// FIXME: explain why it is unsafe,and describe the safety requirements
103    pub unsafe fn add_user(&mut self, inst: InstPtr) {
104        self.user.push(inst);
105    }
106    /// # Safety
107    /// FIXME: explain why it is unsafe,and describe the safety requirements
108    pub unsafe fn remove_user(&mut self, inst: InstPtr) {
109        self.user
110            .iter()
111            .position(|x| *x == inst)
112            .map(|x| self.user.swap_remove(x));
113    }
114}