Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[WIP] Generate name for inner anonymous records #191

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions bindgen/TypeTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,17 +193,21 @@ TypeTranslator::addUnionDefinition(clang::RecordDecl *record,
std::string name) {
std::vector<std::shared_ptr<Field>> fields;

int anonIdField = 0;
for (const clang::FieldDecl *field : record->fields()) {
std::string fname = field->getNameAsString();
std::shared_ptr<Type> ftype = translate(field->getType());

std::string fname = field->getNameAsString();
if (fname.empty()) {
fname = "unnamed_" + std::to_string(anonIdField++);
}
fields.push_back(std::make_shared<Field>(fname, ftype));
}

uint64_t sizeInBits = ctx->getTypeSize(record->getTypeForDecl());
assert(sizeInBits % 8 == 0);

return ir.addUnion(name, std::move(fields), sizeInBits / 8,
return ir.addUnion(std::move(name), std::move(fields), sizeInBits / 8,
getLocation(record));
}

Expand All @@ -222,15 +226,20 @@ TypeTranslator::addStructDefinition(clang::RecordDecl *record,
ctx->getASTRecordLayout(record);

bool isBitFieldStruct = false;
int anonIdField = 0;
for (const clang::FieldDecl *field : record->fields()) {
if (field->isBitField()) {
isBitFieldStruct = true;
}
std::shared_ptr<Type> ftype = translate(field->getType());
uint64_t recordOffsetInBits =
recordLayout.getFieldOffset(field->getFieldIndex());
fields.push_back(std::make_shared<Field>(field->getNameAsString(),
ftype, recordOffsetInBits));
std::string fname = field->getNameAsString();
if (fname.empty()) {
fname = "unnamed_" + std::to_string(anonIdField++);
}
fields.push_back(
std::make_shared<Field>(fname, ftype, recordOffsetInBits));
}

uint64_t sizeInBits = ctx->getTypeSize(record->getTypeForDecl());
Expand Down
6 changes: 5 additions & 1 deletion tests/samples/Struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s) {
return s->anonymousStruct.c;
}

char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s) {
int getIntFromAnonymousStruct(struct structWithAnonymousStruct *s) {
return s->anonymousStruct.i;
}

int getFieldOfUnnamedStruct(struct structWithAnonymousStruct *s) {
return s->b;
}

int struct_test_long(struct bigStruct *s, enum struct_op op, long value) {
switch (op) {
case STRUCT_SET:
Expand Down
8 changes: 7 additions & 1 deletion tests/samples/Struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ struct structWithAnonymousStruct {
char c;
int i;
} anonymousStruct;

struct {
int b;
};
};

struct __attribute__((__packed__)) packedStruct { // no helper methods
Expand All @@ -75,7 +79,9 @@ struct bitFieldOffsetDivByEight { // no helper methods

char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s);

char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s);
int getIntFromAnonymousStruct(struct structWithAnonymousStruct *s);

int getFieldOfUnnamedStruct(struct structWithAnonymousStruct *s);

enum struct_op { STRUCT_SET, STRUCT_TEST };

Expand Down
26 changes: 23 additions & 3 deletions tests/samples/Struct.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ 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_anonymous_0 = native.CStruct2[native.CChar, native.CInt]
type struct_structWithAnonymousStruct = native.CStruct2[native.CInt, struct_anonymous_0]
type struct_anonymous_1 = native.CStruct1[native.CInt]
type struct_structWithAnonymousStruct = native.CStruct3[native.CInt, struct_anonymous_0, struct_anonymous_1]
type struct_packedStruct = native.CStruct1[native.CChar]
type struct_bitFieldStruct = native.CArray[Byte, native.Nat._2]
type struct_bitFieldOffsetDivByEight = native.CArray[Byte, native.Nat._4]
Expand All @@ -35,7 +36,8 @@ object Struct {
def createPoint(): native.Ptr[struct_point] = native.extern
def getBigStructSize(): native.CInt = native.extern
def getCharFromAnonymousStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CChar = native.extern
def getIntFromAnonymousStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CChar = native.extern
def getIntFromAnonymousStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CInt = native.extern
def getFieldOfUnnamedStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CInt = native.extern
def struct_test_long(s: native.Ptr[struct_bigStruct], op: enum_struct_op, value: native.CLong): native.CInt = native.extern
def struct_test_double(s: native.Ptr[struct_bigStruct], op: enum_struct_op, value: native.CDouble): native.CInt = native.extern
def struct_test_point(s: native.Ptr[struct_bigStruct], op: enum_struct_op, value: native.Ptr[struct_point]): native.CInt = native.extern
Expand Down Expand Up @@ -111,11 +113,18 @@ object Struct {
def i_=(value: native.CInt): Unit = !p._2 = value
}

implicit class struct_anonymous_1_ops(val p: native.Ptr[struct_anonymous_1]) extends AnyVal {
def b: native.CInt = !p._1
def b_=(value: native.CInt): Unit = !p._1 = value
}

implicit class struct_structWithAnonymousStruct_ops(val p: native.Ptr[struct_structWithAnonymousStruct]) extends AnyVal {
def a: native.CInt = !p._1
def a_=(value: native.CInt): Unit = !p._1 = value
def anonymousStruct: native.Ptr[struct_anonymous_0] = p._2
def anonymousStruct_=(value: native.Ptr[struct_anonymous_0]): Unit = !p._2 = !value
def unnamed_0: native.Ptr[struct_anonymous_1] = p._3
def unnamed_0_=(value: native.Ptr[struct_anonymous_1]): Unit = !p._3 = !value
}
}

Expand Down Expand Up @@ -184,13 +193,24 @@ object Struct {
}
}

object struct_anonymous_1 {
import implicits._
def apply()(implicit z: native.Zone): native.Ptr[struct_anonymous_1] = native.alloc[struct_anonymous_1]
def apply(b: native.CInt)(implicit z: native.Zone): native.Ptr[struct_anonymous_1] = {
val ptr = native.alloc[struct_anonymous_1]
ptr.b = b
ptr
}
}

object struct_structWithAnonymousStruct {
import implicits._
def apply()(implicit z: native.Zone): native.Ptr[struct_structWithAnonymousStruct] = native.alloc[struct_structWithAnonymousStruct]
def apply(a: native.CInt, anonymousStruct: native.Ptr[struct_anonymous_0])(implicit z: native.Zone): native.Ptr[struct_structWithAnonymousStruct] = {
def apply(a: native.CInt, anonymousStruct: native.Ptr[struct_anonymous_0], unnamed_0: native.Ptr[struct_anonymous_1])(implicit z: native.Zone): native.Ptr[struct_structWithAnonymousStruct] = {
val ptr = native.alloc[struct_structWithAnonymousStruct]
ptr.a = a
ptr.anonymousStruct = anonymousStruct
ptr.unnamed_0 = unnamed_0
ptr
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ class StructSpec extends FunSpec {
}
}

it("should support unnamed structs") {
type struct_unnamedStruct = CStruct1[CInt]
Zone { implicit zone =>
val unnamedStruct: Ptr[struct_unnamedStruct] =
alloc[struct_unnamedStruct]
!unnamedStruct._1 = 42

val structWithAnonymousStruct =
Struct.struct_structWithAnonymousStruct()
structWithAnonymousStruct.unnamed_0 = unnamedStruct

assert(42 == Struct.getFieldOfUnnamedStruct(structWithAnonymousStruct))
}
}

it("should match size of C memory layout for big structs") {
assert(Struct.getBigStructSize() == sizeof[Struct.struct_bigStruct])
}
Expand Down