-
Notifications
You must be signed in to change notification settings - Fork 0
/
BasicBlock.h
111 lines (84 loc) · 2.66 KB
/
BasicBlock.h
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
#pragma once
#include <memory>
#include <ostream>
#include <string>
#include <llvm-c/Core.h>
#include "Instruction.h"
class BasicBlock;
namespace std {
template <> struct hash<BasicBlock> {
size_t operator()(const BasicBlock &bb) const;
};
};
class Function;
class BasicBlock {
LLVMBasicBlockRef bb_ = nullptr;
public:
BasicBlock(LLVMBasicBlockRef &bb):bb_(bb) {}
static BasicBlock fromIntruction(const Instruction &i)
{ return i.getParent(); }
const ::std::string getName() const
{ return ::std::string(LLVMGetBasicBlockName(bb_)); }
Function getParent() const;
bool operator == (const BasicBlock &other) const
{ return bb_ == other.bb_; }
class inst_iterator {
const LLVMBasicBlockRef &bb_;
LLVMValueRef inst_;
::std::unique_ptr<Instruction> instance_ = nullptr;
public:
inst_iterator(const LLVMBasicBlockRef &bb, LLVMValueRef inst):bb_(bb), inst_(inst) {}
bool operator != (const inst_iterator &i)
{ return inst_ != i.inst_; }
Instruction& operator *()
{ return *get_instance_(); }
Instruction* operator -> ()
{ return get_instance_(); }
const inst_iterator & operator++()
{ inst_ = LLVMGetNextInstruction(inst_); instance_ = nullptr; return *this; }
private:
Instruction * get_instance_()
{
if (!instance_)
instance_.reset(new Instruction(inst_));
return instance_.get();
}
};
inst_iterator begin() const
{ return inst_iterator(bb_, LLVMGetFirstInstruction(bb_)); }
inst_iterator end() const
{ return inst_iterator(bb_, nullptr); }
class successor_iterator {
LLVMValueRef bb_term_;
unsigned successor_id_;
::std::unique_ptr<BasicBlock> instance_ = nullptr;
public:
successor_iterator(LLVMBasicBlockRef &bb, int successor = 0):bb_term_(LLVMGetBasicBlockTerminator(bb)), successor_id_(successor)
{
if (successor == -1)
successor_id_ = LLVMGetNumSuccessors(bb_term_);
}
bool operator != (const successor_iterator &i)
{ return successor_id_ != i.successor_id_; }
const successor_iterator & operator++()
{ ++successor_id_; instance_ = nullptr; return *this; }
BasicBlock& operator *()
{ return *get_instance(); }
BasicBlock* operator -> ()
{ return get_instance(); }
private:
BasicBlock *get_instance() {
if (!instance_) {
auto ref = LLVMGetSuccessor(bb_term_, successor_id_);
instance_ = ::std::unique_ptr<BasicBlock>(new BasicBlock(ref));
}
return instance_.get();
}
};
successor_iterator successor_begin()
{ return successor_iterator(bb_); }
successor_iterator successor_end()
{ return successor_iterator(bb_, -1); }
friend ::std::ostream & operator << (::std::ostream &, const BasicBlock &);
friend size_t ::std::hash<BasicBlock>::operator() (const BasicBlock &) const;
};