pipeline_script/llvm/value/
penum.rs

1use llvm_sys::core::LLVMIsUndef;
2use llvm_sys::prelude::LLVMValueRef;
3
4use crate::context::Context;
5use crate::llvm::global::Global;
6use crate::llvm::types::LLVMType;
7use crate::llvm::value::int::Int32Value;
8use crate::llvm::value::LLVMValue;
9
10#[derive(Debug, Clone)]
11pub struct EnumVariantValue {
12    #[allow(unused)]
13    reference: LLVMValueRef,
14    #[allow(unused)]
15    enum_name: String,
16    #[allow(unused)]
17    variant_name: String,
18    tag: Int32Value,
19    value: Option<Box<LLVMValue>>,
20}
21
22impl EnumVariantValue {
23    pub fn new(
24        reference: LLVMValueRef,
25        enum_name: String,
26        variant_name: String,
27        tag: Int32Value,
28        value: Option<Box<LLVMValue>>,
29    ) -> Self {
30        Self {
31            reference,
32            enum_name,
33            variant_name,
34            tag,
35            value,
36        }
37    }
38    pub fn get_reference(&self) -> LLVMValueRef {
39        self.reference
40    }
41    pub fn get_tag(&self) -> Int32Value {
42        self.tag.clone()
43    }
44    pub fn get_value(&self) -> Option<LLVMValue> {
45        self.value.as_ref().map(|v| *v.clone())
46    }
47    pub fn is_undef(&self) -> bool {
48        unsafe { LLVMIsUndef(self.reference) == 1 }
49    }
50    pub fn get_llvm_type(&self, ctx: &Context) -> LLVMType {
51        // 枚举类型在LLVM中被编译为包含标签和数据的结构体
52        let fields = vec![
53            // 标签字段,用于区分不同的变体
54            ("tag".into(), Global::i32_type()),
55            // 数据字段,如果有值则使用值的类型,否则使用i64作为默认类型
56            (
57                "data".into(),
58                self.value
59                    .as_ref()
60                    .map_or(Global::i64_type(), |v| v.get_llvm_type(ctx)),
61            ),
62        ];
63        Global::struct_type(self.enum_name.clone(), fields)
64    }
65}