-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathStructElement.cc
More file actions
50 lines (43 loc) · 1.58 KB
/
StructElement.cc
File metadata and controls
50 lines (43 loc) · 1.58 KB
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
#define DEBUG_TYPE "struct-element"
#include "StructElement.hh"
#include <llvm/IR/Constants.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/Debug.h>
#include <llvm/Support/raw_ostream.h>
using namespace boost;
using namespace llvm;
optional<StructElement> StructElement::get(const llvm::Value &value)
{
//const LoadInst *load;
/*while ((load = dyn_cast<LoadInst>(&value))) {
value = load->getPointerOperand();
}
const StoreInst *store;
while ((store = dyn_cast<StoreInst>(&value))) {
value = store->getPointerOperand();
}*/
if (const llvm::GetElementPtrInst * const gepi = llvm::dyn_cast<llvm::GetElementPtrInst>(&value)) {
const llvm::Type * const pointer = gepi->getPointerOperandType()->getPointerElementType();
if (gepi->getNumIndices() != 2 || !gepi->hasAllConstantIndices()) {
DEBUG(llvm::dbgs() << "Aborting\n");
return none;
}
DEBUG(llvm::dbgs() << "is struct? " << pointer->isStructTy() << "\n");
if (const llvm::StructType * const structTy = llvm::dyn_cast<llvm::StructType>(pointer)) {
auto location = gepi->idx_begin();
//assert that location points to zero here
location++;
const llvm::ConstantInt * const constant = llvm::dyn_cast<llvm::ConstantInt>(location->get());
assert(constant != nullptr);
int index = constant->getSExtValue();
DEBUG(llvm::dbgs() << "Offset of " << index << "\n");
return StructElement(*structTy, index);
}
}
return none;
}
raw_ostream &operator<<(raw_ostream &sink, const StructElement &element)
{
return sink << "struct " << element.structure.getName()
<< '[' << element.index << ']';
}