Skip to content

Commit 977f3e6

Browse files
committed
Generate name for inner anonymous records
1 parent df13474 commit 977f3e6

File tree

5 files changed

+63
-9
lines changed

5 files changed

+63
-9
lines changed

bindgen/TypeTranslator.cpp

+13-4
Original file line numberDiff line numberDiff line change
@@ -193,17 +193,21 @@ TypeTranslator::addUnionDefinition(clang::RecordDecl *record,
193193
std::string name) {
194194
std::vector<std::shared_ptr<Field>> fields;
195195

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

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

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

206-
return ir.addUnion(name, std::move(fields), sizeInBits / 8,
210+
return ir.addUnion(std::move(name), std::move(fields), sizeInBits / 8,
207211
getLocation(record));
208212
}
209213

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

224228
bool isBitFieldStruct = false;
229+
int anonIdField = 0;
225230
for (const clang::FieldDecl *field : record->fields()) {
226231
if (field->isBitField()) {
227232
isBitFieldStruct = true;
228233
}
229234
std::shared_ptr<Type> ftype = translate(field->getType());
230235
uint64_t recordOffsetInBits =
231236
recordLayout.getFieldOffset(field->getFieldIndex());
232-
fields.push_back(std::make_shared<Field>(field->getNameAsString(),
233-
ftype, recordOffsetInBits));
237+
std::string fname = field->getNameAsString();
238+
if (fname.empty()) {
239+
fname = "unnamed_" + std::to_string(anonIdField++);
240+
}
241+
fields.push_back(
242+
std::make_shared<Field>(fname, ftype, recordOffsetInBits));
234243
}
235244

236245
uint64_t sizeInBits = ctx->getTypeSize(record->getTypeForDecl());

tests/samples/Struct.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,14 @@ char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s) {
3434
return s->anonymousStruct.c;
3535
}
3636

37-
char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s) {
37+
int getIntFromAnonymousStruct(struct structWithAnonymousStruct *s) {
3838
return s->anonymousStruct.i;
3939
}
4040

41+
int getFieldOfUnnamedStruct(struct structWithAnonymousStruct *s) {
42+
return s->b;
43+
}
44+
4145
int struct_test_long(struct bigStruct *s, enum struct_op op, long value) {
4246
switch (op) {
4347
case STRUCT_SET:

tests/samples/Struct.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ struct structWithAnonymousStruct {
5454
char c;
5555
int i;
5656
} anonymousStruct;
57+
58+
struct {
59+
int b;
60+
};
5761
};
5862

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

7680
char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s);
7781

78-
char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s);
82+
int getIntFromAnonymousStruct(struct structWithAnonymousStruct *s);
83+
84+
int getFieldOfUnnamedStruct(struct structWithAnonymousStruct *s);
7985

8086
enum struct_op { STRUCT_SET, STRUCT_TEST };
8187

tests/samples/Struct.scala

+23-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ object Struct {
2626
type point_s = native.Ptr[struct_point]
2727
type struct_bigStruct = native.CArray[Byte, native.Nat.Digit[native.Nat._1, native.Nat.Digit[native.Nat._1, native.Nat._2]]]
2828
type struct_anonymous_0 = native.CStruct2[native.CChar, native.CInt]
29-
type struct_structWithAnonymousStruct = native.CStruct2[native.CInt, struct_anonymous_0]
29+
type struct_anonymous_1 = native.CStruct1[native.CInt]
30+
type struct_structWithAnonymousStruct = native.CStruct3[native.CInt, struct_anonymous_0, struct_anonymous_1]
3031
type struct_packedStruct = native.CStruct1[native.CChar]
3132
type struct_bitFieldStruct = native.CArray[Byte, native.Nat._2]
3233
type struct_bitFieldOffsetDivByEight = native.CArray[Byte, native.Nat._4]
@@ -35,7 +36,8 @@ object Struct {
3536
def createPoint(): native.Ptr[struct_point] = native.extern
3637
def getBigStructSize(): native.CInt = native.extern
3738
def getCharFromAnonymousStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CChar = native.extern
38-
def getIntFromAnonymousStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CChar = native.extern
39+
def getIntFromAnonymousStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CInt = native.extern
40+
def getFieldOfUnnamedStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CInt = native.extern
3941
def struct_test_long(s: native.Ptr[struct_bigStruct], op: enum_struct_op, value: native.CLong): native.CInt = native.extern
4042
def struct_test_double(s: native.Ptr[struct_bigStruct], op: enum_struct_op, value: native.CDouble): native.CInt = native.extern
4143
def struct_test_point(s: native.Ptr[struct_bigStruct], op: enum_struct_op, value: native.Ptr[struct_point]): native.CInt = native.extern
@@ -111,11 +113,18 @@ object Struct {
111113
def i_=(value: native.CInt): Unit = !p._2 = value
112114
}
113115

116+
implicit class struct_anonymous_1_ops(val p: native.Ptr[struct_anonymous_1]) extends AnyVal {
117+
def b: native.CInt = !p._1
118+
def b_=(value: native.CInt): Unit = !p._1 = value
119+
}
120+
114121
implicit class struct_structWithAnonymousStruct_ops(val p: native.Ptr[struct_structWithAnonymousStruct]) extends AnyVal {
115122
def a: native.CInt = !p._1
116123
def a_=(value: native.CInt): Unit = !p._1 = value
117124
def anonymousStruct: native.Ptr[struct_anonymous_0] = p._2
118125
def anonymousStruct_=(value: native.Ptr[struct_anonymous_0]): Unit = !p._2 = !value
126+
def unnamed_0: native.Ptr[struct_anonymous_1] = p._3
127+
def unnamed_0_=(value: native.Ptr[struct_anonymous_1]): Unit = !p._3 = !value
119128
}
120129
}
121130

@@ -184,13 +193,24 @@ object Struct {
184193
}
185194
}
186195

196+
object struct_anonymous_1 {
197+
import implicits._
198+
def apply()(implicit z: native.Zone): native.Ptr[struct_anonymous_1] = native.alloc[struct_anonymous_1]
199+
def apply(b: native.CInt)(implicit z: native.Zone): native.Ptr[struct_anonymous_1] = {
200+
val ptr = native.alloc[struct_anonymous_1]
201+
ptr.b = b
202+
ptr
203+
}
204+
}
205+
187206
object struct_structWithAnonymousStruct {
188207
import implicits._
189208
def apply()(implicit z: native.Zone): native.Ptr[struct_structWithAnonymousStruct] = native.alloc[struct_structWithAnonymousStruct]
190-
def apply(a: native.CInt, anonymousStruct: native.Ptr[struct_anonymous_0])(implicit z: native.Zone): native.Ptr[struct_structWithAnonymousStruct] = {
209+
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] = {
191210
val ptr = native.alloc[struct_structWithAnonymousStruct]
192211
ptr.a = a
193212
ptr.anonymousStruct = anonymousStruct
213+
ptr.unnamed_0 = unnamed_0
194214
ptr
195215
}
196216
}

tests/samples/src/test/scala/org/scalanative/bindgen/samples/StructSpec.scala

+15
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ class StructSpec extends FunSpec {
7272
}
7373
}
7474

75+
it("should support unnamed structs") {
76+
type struct_unnamedStruct = CStruct1[CInt]
77+
Zone { implicit zone =>
78+
val unnamedStruct: Ptr[struct_unnamedStruct] =
79+
alloc[struct_unnamedStruct]
80+
!unnamedStruct._1 = 42
81+
82+
val structWithAnonymousStruct =
83+
Struct.struct_structWithAnonymousStruct()
84+
structWithAnonymousStruct.unnamed_0 = unnamedStruct
85+
86+
assert(42 == Struct.getFieldOfUnnamedStruct(structWithAnonymousStruct))
87+
}
88+
}
89+
7590
it("should match size of C memory layout for big structs") {
7691
assert(Struct.getBigStructSize() == sizeof[Struct.struct_bigStruct])
7792
}

0 commit comments

Comments
 (0)