Skip to content

Commit

Permalink
Generate name for inner anonymous records
Browse files Browse the repository at this point in the history
  • Loading branch information
kornilova203 committed Jan 31, 2019
1 parent df13474 commit 977f3e6
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 9 deletions.
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

0 comments on commit 977f3e6

Please sign in to comment.