Skip to content

Commit

Permalink
Merge pull request #125 from kornilova-l/packed-structs
Browse files Browse the repository at this point in the history
Do not generate helper methods for packed structs that are represented as CStruct
  • Loading branch information
kornilova203 authored Jul 18, 2018
2 parents 7aba5e4 + f2368eb commit 9ced3ac
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 8 deletions.
5 changes: 3 additions & 2 deletions bindgen/ir/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ void IR::addEnum(std::string name, const std::string &type,
}

void IR::addStruct(std::string name, std::vector<std::shared_ptr<Field>> fields,
uint64_t typeSize, std::shared_ptr<Location> location) {
uint64_t typeSize, std::shared_ptr<Location> location,
bool isPacked) {
std::shared_ptr<Struct> s = std::make_shared<Struct>(
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> typeDef = getTypeDefWithName("struct_" + name);
if (typeDef) {
Expand Down
3 changes: 2 additions & 1 deletion bindgen/ir/IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class IR {
std::shared_ptr<Location> location);

void addStruct(std::string name, std::vector<std::shared_ptr<Field>> fields,
uint64_t typeSize, std::shared_ptr<Location> location);
uint64_t typeSize, std::shared_ptr<Location> location,
bool isPacked);

void addUnion(std::string name, std::vector<std::shared_ptr<Field>> fields,
uint64_t maxSize, std::shared_ptr<Location> location);
Expand Down
14 changes: 11 additions & 3 deletions bindgen/ir/Struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ std::shared_ptr<Location> StructOrUnion::getLocation() const {
}

Struct::Struct(std::string name, std::vector<std::shared_ptr<Field>> fields,
uint64_t typeSize, std::shared_ptr<Location> location)
uint64_t typeSize, std::shared_ptr<Location> location,
bool isPacked)
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
typeSize(typeSize) {}
typeSize(typeSize), isPacked(isPacked) {}

std::shared_ptr<TypeDef> Struct::generateTypeDef() {
if (fields.size() < SCALA_NATIVE_MAX_STRUCT_FIELDS) {
Expand Down Expand Up @@ -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; }
Expand Down Expand Up @@ -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<std::shared_ptr<Field>> fields,
uint64_t maxSize, std::shared_ptr<Location> location)
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
Expand Down
6 changes: 5 additions & 1 deletion bindgen/ir/Struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class Struct : public StructOrUnion,
public std::enable_shared_from_this<Struct> {
public:
Struct(std::string name, std::vector<std::shared_ptr<Field>> fields,
uint64_t typeSize, std::shared_ptr<Location> location);
uint64_t typeSize, std::shared_ptr<Location> location,
bool isPacked);

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

Expand All @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion bindgen/visitor/TreeVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<clang::PackedAttr>());
}

bool TreeVisitor::VisitVarDecl(clang::VarDecl *varDecl) {
Expand Down
4 changes: 4 additions & 0 deletions tests/samples/Struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
1 change: 1 addition & 0 deletions tests/samples/Struct.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9ced3ac

Please sign in to comment.