From f2368eb8820630e92710bca66a131fa0d21751a6 Mon Sep 17 00:00:00 2001 From: kornilova-l Date: Wed, 18 Jul 2018 22:07:43 +0800 Subject: [PATCH] Do not generate helpers for packed structs --- bindgen/ir/IR.cpp | 5 +++-- bindgen/ir/IR.h | 3 ++- bindgen/ir/Struct.cpp | 14 +++++++++++--- bindgen/ir/Struct.h | 6 +++++- bindgen/visitor/TreeVisitor.cpp | 3 ++- tests/samples/Struct.h | 4 ++++ tests/samples/Struct.scala | 1 + 7 files changed, 28 insertions(+), 8 deletions(-) diff --git a/bindgen/ir/IR.cpp b/bindgen/ir/IR.cpp index f85d148..f7a3ca7 100644 --- a/bindgen/ir/IR.cpp +++ b/bindgen/ir/IR.cpp @@ -33,9 +33,10 @@ void IR::addEnum(std::string name, const std::string &type, } void IR::addStruct(std::string name, std::vector> fields, - uint64_t typeSize, std::shared_ptr location) { + uint64_t typeSize, std::shared_ptr location, + bool isPacked) { std::shared_ptr s = std::make_shared( - name, std::move(fields), typeSize, std::move(location)); + name, std::move(fields), typeSize, std::move(location), isPacked); structs.push_back(s); std::shared_ptr typeDef = getTypeDefWithName("struct_" + name); if (typeDef) { diff --git a/bindgen/ir/IR.h b/bindgen/ir/IR.h index 23340ac..ce61060 100644 --- a/bindgen/ir/IR.h +++ b/bindgen/ir/IR.h @@ -35,7 +35,8 @@ class IR { std::shared_ptr location); void addStruct(std::string name, std::vector> fields, - uint64_t typeSize, std::shared_ptr location); + uint64_t typeSize, std::shared_ptr location, + bool isPacked); void addUnion(std::string name, std::vector> fields, uint64_t maxSize, std::shared_ptr location); diff --git a/bindgen/ir/Struct.cpp b/bindgen/ir/Struct.cpp index e8cd1d5..3735242 100644 --- a/bindgen/ir/Struct.cpp +++ b/bindgen/ir/Struct.cpp @@ -42,9 +42,10 @@ std::shared_ptr StructOrUnion::getLocation() const { } Struct::Struct(std::string name, std::vector> fields, - uint64_t typeSize, std::shared_ptr location) + uint64_t typeSize, std::shared_ptr location, + bool isPacked) : StructOrUnion(std::move(name), std::move(fields), std::move(location)), - typeSize(typeSize) {} + typeSize(typeSize), isPacked(isPacked) {} std::shared_ptr Struct::generateTypeDef() { if (fields.size() < SCALA_NATIVE_MAX_STRUCT_FIELDS) { @@ -89,7 +90,10 @@ std::string Struct::generateHelperClass() const { } bool Struct::hasHelperMethods() const { - return !fields.empty() && fields.size() < SCALA_NATIVE_MAX_STRUCT_FIELDS; + if (!isRepresentedAsStruct()) { + return false; + } + return !isPacked && !fields.empty(); } std::string Struct::getTypeAlias() const { return "struct_" + name; } @@ -160,6 +164,10 @@ std::string Struct::generateGetter(unsigned fieldIndex) const { return s.str(); } +bool Struct::isRepresentedAsStruct() const { + return fields.size() <= SCALA_NATIVE_MAX_STRUCT_FIELDS; +} + Union::Union(std::string name, std::vector> fields, uint64_t maxSize, std::shared_ptr location) : StructOrUnion(std::move(name), std::move(fields), std::move(location)), diff --git a/bindgen/ir/Struct.h b/bindgen/ir/Struct.h index 517abe3..c4fdfa6 100644 --- a/bindgen/ir/Struct.h +++ b/bindgen/ir/Struct.h @@ -42,7 +42,8 @@ class Struct : public StructOrUnion, public std::enable_shared_from_this { public: Struct(std::string name, std::vector> fields, - uint64_t typeSize, std::shared_ptr location); + uint64_t typeSize, std::shared_ptr location, + bool isPacked); std::shared_ptr generateTypeDef() override; @@ -69,6 +70,9 @@ class Struct : public StructOrUnion, private: /* type size is needed if number of fields is bigger than 22 */ uint64_t typeSize; + bool isPacked; + + bool isRepresentedAsStruct() const; }; class Union : public StructOrUnion, diff --git a/bindgen/visitor/TreeVisitor.cpp b/bindgen/visitor/TreeVisitor.cpp index 5a86d9e..1855327 100644 --- a/bindgen/visitor/TreeVisitor.cpp +++ b/bindgen/visitor/TreeVisitor.cpp @@ -149,7 +149,8 @@ void TreeVisitor::handleStruct(clang::RecordDecl *record, std::string name) { uint64_t sizeInBits = astContext->getTypeSize(record->getTypeForDecl()); assert(sizeInBits % 8 == 0); - ir.addStruct(name, std::move(fields), sizeInBits / 8, getLocation(record)); + ir.addStruct(name, std::move(fields), sizeInBits / 8, getLocation(record), + record->hasAttr()); } bool TreeVisitor::VisitVarDecl(clang::VarDecl *varDecl) { diff --git a/tests/samples/Struct.h b/tests/samples/Struct.h index 2acd725..f2a7156 100644 --- a/tests/samples/Struct.h +++ b/tests/samples/Struct.h @@ -56,6 +56,10 @@ struct structWithAnonymousStruct { } anonymousStruct; }; +struct __attribute__((__packed__)) packedStruct { // no helper methods + char a; +}; + char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s); char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s); diff --git a/tests/samples/Struct.scala b/tests/samples/Struct.scala index 1255ee7..101c10b 100644 --- a/tests/samples/Struct.scala +++ b/tests/samples/Struct.scala @@ -13,6 +13,7 @@ object Struct { type point_s = native.Ptr[struct_point] type struct_bigStruct = native.CArray[Byte, native.Nat.Digit[native.Nat._1, native.Nat.Digit[native.Nat._1, native.Nat._2]]] type struct_structWithAnonymousStruct = native.CStruct2[native.CInt, native.CArray[Byte, native.Nat._8]] + type struct_packedStruct = native.CStruct1[native.CChar] def setPoints(points: native.Ptr[struct_points], x1: native.CInt, y1: native.CInt, x2: native.CInt, y2: native.CInt): Unit = native.extern def getPoint(points: native.Ptr[struct_points], pointIndex: enum_pointIndex): native.CInt = native.extern def createPoint(): native.Ptr[struct_point] = native.extern