1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use crate::types::{TypeRef, Typed, Types};
use crate::{ConstantRef, Name};
use std::fmt::{self, Display};
#[derive(PartialEq, Clone, Debug)]
pub enum Operand {
LocalOperand {
name: Name,
ty: TypeRef,
},
ConstantOperand(ConstantRef),
MetadataOperand,
}
impl Typed for Operand {
fn get_type(&self, types: &Types) -> TypeRef {
match self {
Operand::LocalOperand { ty, .. } => ty.clone(),
Operand::ConstantOperand(c) => types.type_of(c),
Operand::MetadataOperand => types.metadata_type(),
}
}
}
impl Operand {
pub fn as_constant(&self) -> Option<&Constant> {
match self {
Operand::ConstantOperand(cref) => Some(&cref),
_ => None,
}
}
}
impl Display for Operand {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Operand::LocalOperand { name, ty } => write!(f, "{} {}", ty, name),
Operand::ConstantOperand(cref) => write!(f, "{}", &cref),
Operand::MetadataOperand => write!(f, "<metadata>"),
}
}
}
use crate::constant::Constant;
use crate::function::FunctionContext;
use crate::llvm_sys::*;
use crate::module::ModuleContext;
use llvm_sys::LLVMValueKind;
impl Operand {
pub(crate) fn from_llvm_ref(
operand: LLVMValueRef,
ctx: &mut ModuleContext,
func_ctx: &FunctionContext,
) -> Self {
let constant = unsafe { LLVMIsAConstant(operand) };
if !constant.is_null() {
Operand::ConstantOperand(Constant::from_llvm_ref(constant, ctx))
} else if unsafe {
LLVMGetValueKind(operand) == LLVMValueKind::LLVMMetadataAsValueValueKind
} {
Operand::MetadataOperand
} else {
Operand::LocalOperand {
name: func_ctx.val_names
.get(&operand)
.unwrap_or_else(|| {
let names: Vec<_> = func_ctx.val_names.values().collect();
let kind = unsafe { LLVMGetValueKind(operand) };
panic!(
"Failed to find operand with kind {:?} in func_ctx.val_names; have names {:?}",
kind, names
)
})
.clone(),
ty: ctx.types.type_from_llvm_ref(unsafe { LLVMTypeOf(operand) }),
}
}
}
}