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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use ffi::core;
use ffi::prelude::LLVMBasicBlockRef;
use std::iter::{DoubleEndedIterator, IntoIterator, Iterator};
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use value::{Function, Value};
use util::{self, Sub};
use builder::Builder;
pub struct BasicBlock(PhantomData<[u8]>);
deref!{BasicBlock, Value}
native_ref!(&BasicBlock = LLVMBasicBlockRef);
unsafe impl Sub<Value> for BasicBlock {
fn is(value: &Value) -> bool {
unsafe { core::LLVMValueIsBasicBlock(value.into()) != 0 }
}
fn from_super(value: &Value) -> Option<&BasicBlock> {
unsafe { mem::transmute(core::LLVMValueAsBasicBlock(value.into())) }
}
fn to_super(&self) -> &Value {
unsafe { core::LLVMBasicBlockAsValue(self.into()).into() }
}
}
impl BasicBlock {
pub fn get_parent(&self) -> Option<&Function> {
unsafe { util::ptr_to_null(core::LLVMGetBasicBlockParent(self.into())) }
}
pub fn get_insert_block<'a>(builder: &'a Builder) -> &'a BasicBlock {
unsafe { core::LLVMGetInsertBlock(builder.into()) }.into()
}
pub fn get_terminator(&self) -> Option<&Value> {
unsafe { util::ptr_to_null(core::LLVMGetBasicBlockTerminator(self.into())) }
}
pub fn get_first(&self) -> Option<&Value> {
unsafe { util::ptr_to_null(core::LLVMGetFirstInstruction(self.into())) }
}
pub fn get_last(&self) -> Option<&Value> {
unsafe { util::ptr_to_null(core::LLVMGetLastInstruction(self.into())) }
}
pub fn move_after(&self, other: &BasicBlock) {
unsafe { core::LLVMMoveBasicBlockAfter(self.into(), other.into()) }
}
pub fn move_before(&self, other: &BasicBlock) {
unsafe { core::LLVMMoveBasicBlockBefore(self.into(), other.into()) }
}
pub fn remove(&self) {
unsafe { core::LLVMRemoveBasicBlockFromParent(self.into()) }
}
pub unsafe fn delete(&self) {
core::LLVMDeleteBasicBlock(self.into())
}
}
pub struct BlockIter<'a> {
pub min: &'a BasicBlock,
pub max: &'a BasicBlock,
}
impl<'a> BlockIter<'a> {
pub fn new(function: &'a Function) -> BlockIter<'a> {
BlockIter {
min: unsafe { core::LLVMGetFirstBasicBlock(function.into()).into() },
max: unsafe { core::LLVMGetLastBasicBlock(function.into()).into() },
}
}
}
impl<'a> IntoIterator for &'a Function {
type IntoIter = BlockIter<'a>;
type Item = &'a BasicBlock;
fn into_iter(self) -> BlockIter<'a> {
BlockIter::new(self)
}
}
impl<'a> Iterator for BlockIter<'a> {
type Item = &'a BasicBlock;
fn next(&mut self) -> Option<&'a BasicBlock> {
if self.min == self.max {
None
} else {
unsafe {
let _block = self.min;
self.min = core::LLVMGetNextBasicBlock(self.min.into()).into();
Some(_block)
}
}
}
}
impl<'a> DoubleEndedIterator for BlockIter<'a> {
fn next_back(&mut self) -> Option<&'a BasicBlock> {
if self.min == self.max {
None
} else {
unsafe {
let _block = self.max;
self.max = core::LLVMGetPreviousBasicBlock(self.max.into()).into();
Some(_block)
}
}
}
}