1*3e457fe3SDavid van Moolenbroek #ifndef BIT_FIELD_AGGREGATION_H
2*3e457fe3SDavid van Moolenbroek #define BIT_FIELD_AGGREGATION_H
3*3e457fe3SDavid van Moolenbroek
4*3e457fe3SDavid van Moolenbroek #include <magic/support/EDIType.h>
5*3e457fe3SDavid van Moolenbroek #include <magic/support/TypeUtil.h>
6*3e457fe3SDavid van Moolenbroek
7*3e457fe3SDavid van Moolenbroek using namespace llvm;
8*3e457fe3SDavid van Moolenbroek
9*3e457fe3SDavid van Moolenbroek namespace llvm {
10*3e457fe3SDavid van Moolenbroek
11*3e457fe3SDavid van Moolenbroek #define BitFieldAggregationErr(M) errs() << "BitFieldAggregation: " << M << "\n"
12*3e457fe3SDavid van Moolenbroek
13*3e457fe3SDavid van Moolenbroek #define BFA_NAME_PREFIX "__BFA__"
14*3e457fe3SDavid van Moolenbroek
15*3e457fe3SDavid van Moolenbroek class BitFieldAggregation {
16*3e457fe3SDavid van Moolenbroek public:
17*3e457fe3SDavid van Moolenbroek BitFieldAggregation(TYPECONST Type* type, std::vector<EDIType> EDITypes, unsigned typeIndex, unsigned EDITypeIndex, std::vector<DIDerivedType> members, unsigned counter);
18*3e457fe3SDavid van Moolenbroek BitFieldAggregation();
19*3e457fe3SDavid van Moolenbroek void init(TYPECONST Type* type, std::vector<EDIType> EDITypes, unsigned typeIndex, unsigned EDITypeIndex, std::vector<DIDerivedType> members, unsigned counter);
20*3e457fe3SDavid van Moolenbroek
21*3e457fe3SDavid van Moolenbroek const std::string getDescription() const;
22*3e457fe3SDavid van Moolenbroek
23*3e457fe3SDavid van Moolenbroek unsigned getTypeIndex() const;
24*3e457fe3SDavid van Moolenbroek unsigned getEDITypeIndex() const;
25*3e457fe3SDavid van Moolenbroek std::string getName() const;
26*3e457fe3SDavid van Moolenbroek std::vector<DIDerivedType> getMembers() const;
27*3e457fe3SDavid van Moolenbroek
28*3e457fe3SDavid van Moolenbroek unsigned getSize() const;
29*3e457fe3SDavid van Moolenbroek TYPECONST Type *getType() const;
30*3e457fe3SDavid van Moolenbroek std::vector<EDIType> getEDITypes() const;
31*3e457fe3SDavid van Moolenbroek unsigned getRepresentativeEDITypeIndex() const;
32*3e457fe3SDavid van Moolenbroek
33*3e457fe3SDavid van Moolenbroek void print(raw_ostream &OS) const;
34*3e457fe3SDavid van Moolenbroek
35*3e457fe3SDavid van Moolenbroek static bool getBitFieldAggregations(TYPECONST Type *type, const EDIType *aEDIType, std::vector<BitFieldAggregation> &bfas, bool returnOnError=false);
36*3e457fe3SDavid van Moolenbroek static bool hasBitFields(TYPECONST Type *type, const EDIType *aEDIType);
37*3e457fe3SDavid van Moolenbroek static bool isBitField(TYPECONST Type *type, const EDIType *aEDIType, unsigned memberIdx);
38*3e457fe3SDavid van Moolenbroek
39*3e457fe3SDavid van Moolenbroek private:
40*3e457fe3SDavid van Moolenbroek TYPECONST Type *type;
41*3e457fe3SDavid van Moolenbroek std::vector<EDIType> EDITypes;
42*3e457fe3SDavid van Moolenbroek unsigned typeIndex;
43*3e457fe3SDavid van Moolenbroek unsigned EDITypeIndex;
44*3e457fe3SDavid van Moolenbroek std::string name;
45*3e457fe3SDavid van Moolenbroek std::vector<DIDerivedType> members;
46*3e457fe3SDavid van Moolenbroek unsigned size;
47*3e457fe3SDavid van Moolenbroek
48*3e457fe3SDavid van Moolenbroek static std::string bfaNamePrefix;
49*3e457fe3SDavid van Moolenbroek
50*3e457fe3SDavid van Moolenbroek static BitFieldAggregation* getBitFieldAggregation(TYPECONST Type *type, const EDIType *aEDIType, bool returnOnError, unsigned typeIndex, unsigned EDITypeIndex, unsigned lastTypeIndex, unsigned lastEDITypeIndex, unsigned counter);
51*3e457fe3SDavid van Moolenbroek };
52*3e457fe3SDavid van Moolenbroek
53*3e457fe3SDavid van Moolenbroek inline raw_ostream &operator<<(raw_ostream &OS, const BitFieldAggregation &bfa) {
54*3e457fe3SDavid van Moolenbroek bfa.print(OS);
55*3e457fe3SDavid van Moolenbroek return OS;
56*3e457fe3SDavid van Moolenbroek }
57*3e457fe3SDavid van Moolenbroek
getTypeIndex()58*3e457fe3SDavid van Moolenbroek inline unsigned BitFieldAggregation::getTypeIndex() const {
59*3e457fe3SDavid van Moolenbroek return typeIndex;
60*3e457fe3SDavid van Moolenbroek }
61*3e457fe3SDavid van Moolenbroek
getEDITypeIndex()62*3e457fe3SDavid van Moolenbroek inline unsigned BitFieldAggregation::getEDITypeIndex() const {
63*3e457fe3SDavid van Moolenbroek return EDITypeIndex;
64*3e457fe3SDavid van Moolenbroek }
65*3e457fe3SDavid van Moolenbroek
getName()66*3e457fe3SDavid van Moolenbroek inline std::string BitFieldAggregation::getName() const {
67*3e457fe3SDavid van Moolenbroek return name;
68*3e457fe3SDavid van Moolenbroek }
69*3e457fe3SDavid van Moolenbroek
getMembers()70*3e457fe3SDavid van Moolenbroek inline std::vector<DIDerivedType> BitFieldAggregation::getMembers() const {
71*3e457fe3SDavid van Moolenbroek return members;
72*3e457fe3SDavid van Moolenbroek }
73*3e457fe3SDavid van Moolenbroek
getSize()74*3e457fe3SDavid van Moolenbroek inline unsigned BitFieldAggregation::getSize() const {
75*3e457fe3SDavid van Moolenbroek return size;
76*3e457fe3SDavid van Moolenbroek }
77*3e457fe3SDavid van Moolenbroek
getType()78*3e457fe3SDavid van Moolenbroek inline TYPECONST Type *BitFieldAggregation::getType() const {
79*3e457fe3SDavid van Moolenbroek return type;
80*3e457fe3SDavid van Moolenbroek }
81*3e457fe3SDavid van Moolenbroek
getEDITypes()82*3e457fe3SDavid van Moolenbroek inline std::vector<EDIType> BitFieldAggregation::getEDITypes() const {
83*3e457fe3SDavid van Moolenbroek return EDITypes;
84*3e457fe3SDavid van Moolenbroek }
85*3e457fe3SDavid van Moolenbroek
getRepresentativeEDITypeIndex()86*3e457fe3SDavid van Moolenbroek inline unsigned BitFieldAggregation::getRepresentativeEDITypeIndex() const {
87*3e457fe3SDavid van Moolenbroek return EDITypeIndex;
88*3e457fe3SDavid van Moolenbroek }
89*3e457fe3SDavid van Moolenbroek
print(raw_ostream & OS)90*3e457fe3SDavid van Moolenbroek inline void BitFieldAggregation::print(raw_ostream &OS) const {
91*3e457fe3SDavid van Moolenbroek OS << getDescription();
92*3e457fe3SDavid van Moolenbroek }
93*3e457fe3SDavid van Moolenbroek
hasBitFields(TYPECONST Type * type,const EDIType * aEDIType)94*3e457fe3SDavid van Moolenbroek inline bool BitFieldAggregation::hasBitFields(TYPECONST Type *type, const EDIType *aEDIType) {
95*3e457fe3SDavid van Moolenbroek if(!aEDIType->isStructTy()) {
96*3e457fe3SDavid van Moolenbroek return false;
97*3e457fe3SDavid van Moolenbroek }
98*3e457fe3SDavid van Moolenbroek unsigned numContainedTypes = aEDIType->getNumContainedTypes();
99*3e457fe3SDavid van Moolenbroek for(unsigned i=0;i<numContainedTypes;i++) {
100*3e457fe3SDavid van Moolenbroek if (isBitField(type, aEDIType, i)) {
101*3e457fe3SDavid van Moolenbroek return true;
102*3e457fe3SDavid van Moolenbroek }
103*3e457fe3SDavid van Moolenbroek }
104*3e457fe3SDavid van Moolenbroek return false;
105*3e457fe3SDavid van Moolenbroek }
106*3e457fe3SDavid van Moolenbroek
isBitField(TYPECONST Type * type,const EDIType * aEDIType,unsigned memberIdx)107*3e457fe3SDavid van Moolenbroek inline bool BitFieldAggregation::isBitField(TYPECONST Type *type, const EDIType *aEDIType, unsigned memberIdx) {
108*3e457fe3SDavid van Moolenbroek const DIDerivedType subDIType = aEDIType->getMember(memberIdx);
109*3e457fe3SDavid van Moolenbroek unsigned EDITypeBits = subDIType.getSizeInBits();
110*3e457fe3SDavid van Moolenbroek const DIType aDIType = PassUtil::getDITypeDerivedFrom(subDIType);
111*3e457fe3SDavid van Moolenbroek unsigned EDITypeOriginalBits = aDIType.getSizeInBits();
112*3e457fe3SDavid van Moolenbroek return (EDITypeBits>0 && EDITypeOriginalBits>0 && EDITypeBits != EDITypeOriginalBits);
113*3e457fe3SDavid van Moolenbroek }
114*3e457fe3SDavid van Moolenbroek
115*3e457fe3SDavid van Moolenbroek }
116*3e457fe3SDavid van Moolenbroek
117*3e457fe3SDavid van Moolenbroek #endif
118