summaryrefslogtreecommitdiff
path: root/minix/llvm/passes/include/magic/support/BitFieldAggregation.h
blob: ac53beba44799a4e9f3f03196445f73e353975fe (plain)
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
112
113
114
115
116
117
#ifndef BIT_FIELD_AGGREGATION_H
#define BIT_FIELD_AGGREGATION_H

#include <magic/support/EDIType.h>
#include <magic/support/TypeUtil.h>

using namespace llvm;

namespace llvm {

#define BitFieldAggregationErr(M) errs() << "BitFieldAggregation: " << M << "\n"

#define BFA_NAME_PREFIX "__BFA__"

class BitFieldAggregation {
  public:
      BitFieldAggregation(TYPECONST Type* type, std::vector<EDIType> EDITypes, unsigned typeIndex, unsigned EDITypeIndex, std::vector<DIDerivedType> members, unsigned counter);
      BitFieldAggregation();
      void init(TYPECONST Type* type, std::vector<EDIType> EDITypes, unsigned typeIndex, unsigned EDITypeIndex, std::vector<DIDerivedType> members, unsigned counter);

      const std::string getDescription() const;

      unsigned getTypeIndex() const;
      unsigned getEDITypeIndex() const;
      std::string getName() const;
      std::vector<DIDerivedType> getMembers() const;

      unsigned getSize() const;
      TYPECONST Type *getType() const;
      std::vector<EDIType> getEDITypes() const;
      unsigned getRepresentativeEDITypeIndex() const;

      void print(raw_ostream &OS) const;

      static bool getBitFieldAggregations(TYPECONST Type *type, const EDIType *aEDIType, std::vector<BitFieldAggregation> &bfas, bool returnOnError=false);
      static bool hasBitFields(TYPECONST Type *type, const EDIType *aEDIType);
      static bool isBitField(TYPECONST Type *type, const EDIType *aEDIType, unsigned memberIdx);

  private:
      TYPECONST Type *type;
      std::vector<EDIType> EDITypes;
      unsigned typeIndex;
      unsigned EDITypeIndex;
      std::string name;
      std::vector<DIDerivedType> members;
      unsigned size;

      static std::string bfaNamePrefix;

      static BitFieldAggregation* getBitFieldAggregation(TYPECONST Type *type, const EDIType *aEDIType, bool returnOnError, unsigned typeIndex, unsigned EDITypeIndex, unsigned lastTypeIndex, unsigned lastEDITypeIndex, unsigned counter);
};

inline raw_ostream &operator<<(raw_ostream &OS, const BitFieldAggregation &bfa) {
    bfa.print(OS);
    return OS;
}

inline unsigned BitFieldAggregation::getTypeIndex() const {
    return typeIndex;
}

inline unsigned BitFieldAggregation::getEDITypeIndex() const {
    return EDITypeIndex;
}

inline std::string BitFieldAggregation::getName() const {
    return name;
}

inline std::vector<DIDerivedType> BitFieldAggregation::getMembers() const {
    return members;
}

inline unsigned BitFieldAggregation::getSize() const {
    return size;
}

inline TYPECONST Type *BitFieldAggregation::getType() const {
    return type;
}

inline std::vector<EDIType> BitFieldAggregation::getEDITypes() const {
    return EDITypes;
}

inline unsigned BitFieldAggregation::getRepresentativeEDITypeIndex() const {
    return EDITypeIndex;
}

inline void BitFieldAggregation::print(raw_ostream &OS) const {
     OS << getDescription();
}

inline bool BitFieldAggregation::hasBitFields(TYPECONST Type *type, const EDIType *aEDIType) {
    if(!aEDIType->isStructTy()) {
        return false;
    }
    unsigned numContainedTypes = aEDIType->getNumContainedTypes();
    for(unsigned i=0;i<numContainedTypes;i++) {
        if (isBitField(type, aEDIType, i)) {
            return true;
        }
    }
    return false;
}

inline bool BitFieldAggregation::isBitField(TYPECONST Type *type, const EDIType *aEDIType, unsigned memberIdx) {
    const DIDerivedType subDIType = aEDIType->getMember(memberIdx);
    unsigned EDITypeBits = subDIType.getSizeInBits();
    const DIType aDIType = PassUtil::getDITypeDerivedFrom(subDIType);
    unsigned EDITypeOriginalBits = aDIType.getSizeInBits();
    return (EDITypeBits>0 && EDITypeOriginalBits>0 && EDITypeBits != EDITypeOriginalBits);
}

}

#endif