1extern crate llvm_sys;
2
3use self::llvm_sys::core::*;
4use self::llvm_sys::prelude::*;
5use cstring_manager::CStringManager;
6
7#[derive(Debug)]
8pub struct Phi {
9 llvm_phi: LLVMValueRef
10}
11
12impl Phi {
13 pub fn new(builder: LLVMBuilderRef, typ: LLVMTypeRef, name: &str) -> Phi {
14 let name_ptr = CStringManager::new_cstring_as_ptr(name);
15 let phi = unsafe { LLVMBuildPhi(builder, typ, name_ptr) };
16 Phi {
17 llvm_phi: phi
18 }
19 }
20
21 pub fn as_ref(&self) -> LLVMValueRef {
22 self.llvm_phi
23 }
24
25 #[inline]
26 pub fn add_incoming(&self, value: LLVMValueRef, block: LLVMBasicBlockRef){
27 let mut values = [value];
28 let mut blocks = [block];
29 self.add_incomings(&mut values, &mut blocks);
30 }
31
32 #[inline]
33 pub fn add_incomings(&self, values: &mut [LLVMValueRef], blocks: &mut [LLVMBasicBlockRef]){
34 let count = values.len();
35 if count != blocks.len() {
36 panic!("values count not equal blocks count.");
37 }
38 unsafe {
39 LLVMAddIncoming(self.llvm_phi, values.as_mut_ptr(), blocks.as_mut_ptr(), count as u32)
40 }
41 }
42
43 #[inline]
44 pub fn incoming_count(&self) -> u32 {
45 unsafe { LLVMCountIncoming(self.llvm_phi) }
46 }
47
48 #[inline]
49 pub fn get_incoming(&self, index: u32) -> (LLVMValueRef, LLVMBasicBlockRef) {
50 let value = unsafe { LLVMGetIncomingValue(self.llvm_phi, index) };
51 let block = unsafe { LLVMGetIncomingBlock(self.llvm_phi, index) };
52 (value, block)
53 }
54}