Skip to content

Commit c25a757

Browse files
committed
Proper way to check bit fields
1 parent ecc5aa2 commit c25a757

File tree

7 files changed

+26
-24
lines changed

7 files changed

+26
-24
lines changed

bindgen/ir/IR.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ void IR::addEnum(std::string name, const std::string &type,
3434

3535
void IR::addStruct(std::string name, std::vector<std::shared_ptr<Field>> fields,
3636
uint64_t typeSize, std::shared_ptr<Location> location,
37-
bool isPacked) {
38-
std::shared_ptr<Struct> s = std::make_shared<Struct>(
39-
name, std::move(fields), typeSize, std::move(location), isPacked);
37+
bool isPacked, bool isBitField) {
38+
std::shared_ptr<Struct> s =
39+
std::make_shared<Struct>(name, std::move(fields), typeSize,
40+
std::move(location), isPacked, isBitField);
4041
structs.push_back(s);
4142
std::shared_ptr<TypeDef> typeDef = getTypeDefWithName("struct_" + name);
4243
if (typeDef) {

bindgen/ir/IR.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class IR {
3636

3737
void addStruct(std::string name, std::vector<std::shared_ptr<Field>> fields,
3838
uint64_t typeSize, std::shared_ptr<Location> location,
39-
bool isPacked);
39+
bool isPacked, bool isBitField);
4040

4141
void addUnion(std::string name, std::vector<std::shared_ptr<Field>> fields,
4242
uint64_t maxSize, std::shared_ptr<Location> location);

bindgen/ir/Struct.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ bool StructOrUnion::hasHelperMethods() const { return !fields.empty(); }
3131

3232
Struct::Struct(std::string name, std::vector<std::shared_ptr<Field>> fields,
3333
uint64_t typeSize, std::shared_ptr<Location> location,
34-
bool isPacked)
34+
bool isPacked, bool isBitField)
3535
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
36-
typeSize(typeSize), isPacked(isPacked) {}
36+
typeSize(typeSize), isPacked(isPacked), isBitField(isBitField) {}
3737

3838
std::shared_ptr<TypeDef> Struct::generateTypeDef() {
3939
if (isRepresentedAsStruct()) {
@@ -74,7 +74,7 @@ std::string Struct::generateHelperClass() const {
7474
}
7575

7676
bool Struct::hasHelperMethods() const {
77-
if (isBitField()) {
77+
if (isBitField) {
7878
return false;
7979
}
8080
if (!isRepresentedAsStruct()) {
@@ -181,7 +181,7 @@ Struct::generateGetterForStructRepresentation(unsigned fieldIndex) const {
181181
}
182182

183183
bool Struct::isRepresentedAsStruct() const {
184-
return fields.size() <= SCALA_NATIVE_MAX_STRUCT_FIELDS && !isBitField();
184+
return fields.size() <= SCALA_NATIVE_MAX_STRUCT_FIELDS && !isBitField;
185185
}
186186

187187
std::string
@@ -242,16 +242,6 @@ Struct::generateGetterForArrayRepresentation(unsigned fieldIndex) const {
242242
return s.str();
243243
}
244244

245-
bool Struct::isBitField() const {
246-
// TODO: find proper way to check it
247-
for (const auto &field : fields) {
248-
if (field->getOffsetInBits() % 8 != 0) {
249-
return true;
250-
}
251-
}
252-
return false;
253-
}
254-
255245
Union::Union(std::string name, std::vector<std::shared_ptr<Field>> fields,
256246
uint64_t maxSize, std::shared_ptr<Location> location)
257247
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),

bindgen/ir/Struct.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ class Struct : public StructOrUnion,
5252
public std::enable_shared_from_this<Struct> {
5353
public:
5454
Struct(std::string name, std::vector<std::shared_ptr<Field>> fields,
55-
uint64_t typeSize, std::shared_ptr<Location> location,
56-
bool isPacked);
55+
uint64_t typeSize, std::shared_ptr<Location> location, bool isPacked,
56+
bool isBitField);
5757

5858
std::shared_ptr<TypeDef> generateTypeDef() override;
5959

@@ -74,9 +74,11 @@ class Struct : public StructOrUnion,
7474
bool operator==(const Type &other) const override;
7575

7676
private:
77-
/* type size is needed if number of fields is bigger than 22 */
77+
/** type size is needed if number of fields is bigger than 22 */
7878
uint64_t typeSize;
7979
bool isPacked;
80+
/** true if at least one field is bit field */
81+
bool isBitField;
8082

8183
bool isRepresentedAsStruct() const;
8284

@@ -99,8 +101,6 @@ class Struct : public StructOrUnion,
99101
std::string generateSetterForArrayRepresentation(unsigned fieldIndex) const;
100102

101103
std::string generateGetterForArrayRepresentation(unsigned fieldIndex) const;
102-
103-
bool isBitField() const;
104104
};
105105

106106
class Union : public StructOrUnion,

bindgen/visitor/TreeVisitor.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,11 @@ void TreeVisitor::handleStruct(clang::RecordDecl *record, std::string name) {
130130
const clang::ASTRecordLayout &recordLayout =
131131
astContext->getASTRecordLayout(record);
132132

133+
bool isBitFieldStruct = false;
133134
for (const clang::FieldDecl *field : record->fields()) {
135+
if (field->isBitField()) {
136+
isBitFieldStruct = true;
137+
}
134138
std::shared_ptr<Type> ftype =
135139
typeTranslator.translate(field->getType(), &name);
136140
uint64_t recordOffsetInBits =
@@ -155,7 +159,7 @@ void TreeVisitor::handleStruct(clang::RecordDecl *record, std::string name) {
155159
assert(sizeInBits % 8 == 0);
156160

157161
ir.addStruct(name, std::move(fields), sizeInBits / 8, getLocation(record),
158-
record->hasAttr<clang::PackedAttr>());
162+
record->hasAttr<clang::PackedAttr>(), isBitFieldStruct);
159163
}
160164

161165
bool TreeVisitor::VisitVarDecl(clang::VarDecl *varDecl) {

tests/samples/Struct.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ struct bitFieldStruct { // no helper methods
6767
unsigned char b3 : 2;
6868
};
6969

70+
struct bitFieldOffsetDivByEight { // no helper methods
71+
unsigned b1 : 8;
72+
unsigned b2 : 8;
73+
unsigned char b3 : 8;
74+
};
75+
7076
char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s);
7177

7278
char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s);

tests/samples/Struct.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ object Struct {
1515
type struct_structWithAnonymousStruct = native.CStruct2[native.CInt, native.CArray[Byte, native.Nat._8]]
1616
type struct_packedStruct = native.CStruct1[native.CChar]
1717
type struct_bitFieldStruct = native.CArray[Byte, native.Nat._2]
18+
type struct_bitFieldOffsetDivByEight = native.CArray[Byte, native.Nat._4]
1819
type enum_struct_op = native.CUnsignedInt
1920
def setPoints(points: native.Ptr[struct_points], x1: native.CInt, y1: native.CInt, x2: native.CInt, y2: native.CInt): Unit = native.extern
2021
def getPoint(points: native.Ptr[struct_points], pointIndex: enum_pointIndex): native.CInt = native.extern

0 commit comments

Comments
 (0)