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