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