Skip to content

Commit 9ced3ac

Browse files
authored
Merge pull request #125 from kornilova-l/packed-structs
Do not generate helper methods for packed structs that are represented as CStruct
2 parents 7aba5e4 + f2368eb commit 9ced3ac

File tree

7 files changed

+28
-8
lines changed

7 files changed

+28
-8
lines changed

bindgen/ir/IR.cpp

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

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

bindgen/ir/IR.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ class IR {
3535
std::shared_ptr<Location> location);
3636

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

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

bindgen/ir/Struct.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ std::shared_ptr<Location> StructOrUnion::getLocation() const {
4242
}
4343

4444
Struct::Struct(std::string name, std::vector<std::shared_ptr<Field>> fields,
45-
uint64_t typeSize, std::shared_ptr<Location> location)
45+
uint64_t typeSize, std::shared_ptr<Location> location,
46+
bool isPacked)
4647
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
47-
typeSize(typeSize) {}
48+
typeSize(typeSize), isPacked(isPacked) {}
4849

4950
std::shared_ptr<TypeDef> Struct::generateTypeDef() {
5051
if (fields.size() < SCALA_NATIVE_MAX_STRUCT_FIELDS) {
@@ -89,7 +90,10 @@ std::string Struct::generateHelperClass() const {
8990
}
9091

9192
bool Struct::hasHelperMethods() const {
92-
return !fields.empty() && fields.size() < SCALA_NATIVE_MAX_STRUCT_FIELDS;
93+
if (!isRepresentedAsStruct()) {
94+
return false;
95+
}
96+
return !isPacked && !fields.empty();
9397
}
9498

9599
std::string Struct::getTypeAlias() const { return "struct_" + name; }
@@ -160,6 +164,10 @@ std::string Struct::generateGetter(unsigned fieldIndex) const {
160164
return s.str();
161165
}
162166

167+
bool Struct::isRepresentedAsStruct() const {
168+
return fields.size() <= SCALA_NATIVE_MAX_STRUCT_FIELDS;
169+
}
170+
163171
Union::Union(std::string name, std::vector<std::shared_ptr<Field>> fields,
164172
uint64_t maxSize, std::shared_ptr<Location> location)
165173
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),

bindgen/ir/Struct.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ class Struct : public StructOrUnion,
4242
public std::enable_shared_from_this<Struct> {
4343
public:
4444
Struct(std::string name, std::vector<std::shared_ptr<Field>> fields,
45-
uint64_t typeSize, std::shared_ptr<Location> location);
45+
uint64_t typeSize, std::shared_ptr<Location> location,
46+
bool isPacked);
4647

4748
std::shared_ptr<TypeDef> generateTypeDef() override;
4849

@@ -69,6 +70,9 @@ class Struct : public StructOrUnion,
6970
private:
7071
/* type size is needed if number of fields is bigger than 22 */
7172
uint64_t typeSize;
73+
bool isPacked;
74+
75+
bool isRepresentedAsStruct() const;
7276
};
7377

7478
class Union : public StructOrUnion,

bindgen/visitor/TreeVisitor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ void TreeVisitor::handleStruct(clang::RecordDecl *record, std::string name) {
149149
uint64_t sizeInBits = astContext->getTypeSize(record->getTypeForDecl());
150150
assert(sizeInBits % 8 == 0);
151151

152-
ir.addStruct(name, std::move(fields), sizeInBits / 8, getLocation(record));
152+
ir.addStruct(name, std::move(fields), sizeInBits / 8, getLocation(record),
153+
record->hasAttr<clang::PackedAttr>());
153154
}
154155

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

tests/samples/Struct.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ struct structWithAnonymousStruct {
5656
} anonymousStruct;
5757
};
5858

59+
struct __attribute__((__packed__)) packedStruct { // no helper methods
60+
char a;
61+
};
62+
5963
char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s);
6064

6165
char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s);

tests/samples/Struct.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ object Struct {
1313
type point_s = native.Ptr[struct_point]
1414
type struct_bigStruct = native.CArray[Byte, native.Nat.Digit[native.Nat._1, native.Nat.Digit[native.Nat._1, native.Nat._2]]]
1515
type struct_structWithAnonymousStruct = native.CStruct2[native.CInt, native.CArray[Byte, native.Nat._8]]
16+
type struct_packedStruct = native.CStruct1[native.CChar]
1617
def setPoints(points: native.Ptr[struct_points], x1: native.CInt, y1: native.CInt, x2: native.CInt, y2: native.CInt): Unit = native.extern
1718
def getPoint(points: native.Ptr[struct_points], pointIndex: enum_pointIndex): native.CInt = native.extern
1819
def createPoint(): native.Ptr[struct_point] = native.extern

0 commit comments

Comments
 (0)