aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cgo/libclang.go8
-rw-r--r--cgo/testdata/types.go24
-rw-r--r--cgo/testdata/types.out.go37
-rw-r--r--testdata/cgo/main.go5
-rw-r--r--testdata/cgo/main.h25
5 files changed, 87 insertions, 12 deletions
diff --git a/cgo/libclang.go b/cgo/libclang.go
index d495384e7..46eff01c0 100644
--- a/cgo/libclang.go
+++ b/cgo/libclang.go
@@ -667,7 +667,13 @@ func tinygo_clang_struct_visitor(c, parent C.GoCXCursor, client_data C.CXClientD
bitfieldNum := passed.bitfieldNum
bitfieldList := passed.bitfieldList
pos := p.getCursorPosition(c)
- if cursorKind := C.tinygo_clang_getCursorKind(c); cursorKind != C.CXCursor_FieldDecl {
+ switch cursorKind := C.tinygo_clang_getCursorKind(c); cursorKind {
+ case C.CXCursor_FieldDecl:
+ // Expected. This is a regular field.
+ case C.CXCursor_StructDecl, C.CXCursor_UnionDecl:
+ // Ignore. The next field will be the struct/union itself.
+ return C.CXChildVisit_Continue
+ default:
cursorKindSpelling := getString(C.clang_getCursorKindSpelling(cursorKind))
p.addError(pos, fmt.Sprintf("expected FieldDecl in struct or union, not %s", cursorKindSpelling))
return C.CXChildVisit_Continue
diff --git a/cgo/testdata/types.go b/cgo/testdata/types.go
index 0c8668cbe..2aa0982a4 100644
--- a/cgo/testdata/types.go
+++ b/cgo/testdata/types.go
@@ -44,7 +44,23 @@ typedef union union2d {
} union2d_t;
typedef union {
unsigned char arr[10];
-} unionarrary_t;
+} unionarray_t;
+
+// Nested structs and unions.
+typedef struct {
+ point2d_t begin;
+ point2d_t end;
+ int tag;
+ union {
+ point2d_t area;
+ point3d_t solid;
+ } coord;
+} struct_nested_t;
+typedef union {
+ point3d_t point;
+ unionarray_t array;
+ union3_t thing;
+} union_nested_t;
// Enums. These define constant numbers. All these constants must be given the
// correct number.
@@ -108,7 +124,11 @@ var (
_ C.union1_t
_ C.union3_t
_ C.union2d_t
- _ C.unionarrary_t
+ _ C.unionarray_t
+
+ // Nested structs and unions.
+ _ C.struct_nested_t
+ _ C.union_nested_t
// Enums (anonymous and named).
_ C.option_t
diff --git a/cgo/testdata/types.out.go b/cgo/testdata/types.out.go
index d0fcc5a22..8a750080b 100644
--- a/cgo/testdata/types.out.go
+++ b/cgo/testdata/types.out.go
@@ -34,7 +34,7 @@ type C.uint uint32
type C.ulong uint32
type C.ulonglong uint64
type C.ushort uint16
-type C.bitfield_t = C.struct_2
+type C.bitfield_t = C.struct_4
type C.myIntArray = [10]C.int
type C.myint = C.int
type C.option2_t = C.uint
@@ -44,6 +44,13 @@ type C.point2d_t = struct {
y C.int
}
type C.point3d_t = C.struct_point3d
+type C.struct_nested_t = struct {
+ begin C.point2d_t
+ end C.point2d_t
+ tag C.int
+
+ coord C.union_2
+}
type C.types_t = struct {
f float32
d float64
@@ -52,22 +59,23 @@ type C.types_t = struct {
type C.union1_t = struct{ i C.int }
type C.union2d_t = C.union_union2d
type C.union3_t = C.union_1
-type C.unionarrary_t = struct{ arr [10]C.uchar }
+type C.union_nested_t = C.union_3
+type C.unionarray_t = struct{ arr [10]C.uchar }
-func (s *C.struct_2) bitfield_a() C.uchar { return s.__bitfield_1 & 0x1f }
-func (s *C.struct_2) set_bitfield_a(value C.uchar) { s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0 }
-func (s *C.struct_2) bitfield_b() C.uchar {
+func (s *C.struct_4) bitfield_a() C.uchar { return s.__bitfield_1 & 0x1f }
+func (s *C.struct_4) set_bitfield_a(value C.uchar) { s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0 }
+func (s *C.struct_4) bitfield_b() C.uchar {
return s.__bitfield_1 >> 5 & 0x1
}
-func (s *C.struct_2) set_bitfield_b(value C.uchar) { s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5 }
-func (s *C.struct_2) bitfield_c() C.uchar {
+func (s *C.struct_4) set_bitfield_b(value C.uchar) { s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5 }
+func (s *C.struct_4) bitfield_c() C.uchar {
return s.__bitfield_1 >> 6
}
-func (s *C.struct_2) set_bitfield_c(value C.uchar,
+func (s *C.struct_4) set_bitfield_c(value C.uchar,
) { s.__bitfield_1 = s.__bitfield_1&0x3f | value<<6 }
-type C.struct_2 struct {
+type C.struct_4 struct {
start C.uchar
__bitfield_1 C.uchar
@@ -92,6 +100,17 @@ func (union *C.union_1) unionfield_s() *C.short { return (*C.short)(unsafe.Point
type C.union_1 struct{ $union uint64 }
+func (union *C.union_2) unionfield_area() *C.point2d_t { return (*C.point2d_t)(unsafe.Pointer(&union.$union)) }
+func (union *C.union_2) unionfield_solid() *C.point3d_t { return (*C.point3d_t)(unsafe.Pointer(&union.$union)) }
+
+type C.union_2 struct{ $union [3]uint32 }
+
+func (union *C.union_3) unionfield_point() *C.point3d_t { return (*C.point3d_t)(unsafe.Pointer(&union.$union)) }
+func (union *C.union_3) unionfield_array() *C.unionarray_t { return (*C.unionarray_t)(unsafe.Pointer(&union.$union)) }
+func (union *C.union_3) unionfield_thing() *C.union3_t { return (*C.union3_t)(unsafe.Pointer(&union.$union)) }
+
+type C.union_3 struct{ $union [2]uint64 }
+
func (union *C.union_union2d) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) }
func (union *C.union_union2d) unionfield_d() *[2]float64 { return (*[2]float64)(unsafe.Pointer(&union.$union)) }
diff --git a/testdata/cgo/main.go b/testdata/cgo/main.go
index 9a1112438..41bc6892c 100644
--- a/testdata/cgo/main.go
+++ b/testdata/cgo/main.go
@@ -80,6 +80,11 @@ func main() {
var _ C.point2d_t = C.point2d_t{x: 3, y: 5}
var _ C.point3d_t = C.point3d_t{x: 3, y: 5, z: 7}
+ // nested structs/unions
+ var _ C.tagged_union_t
+ var _ C.nested_struct_t
+ var _ C.nested_union_t
+
// recursive types, test using a linked list
list := &C.list_t{n: 3, next: &C.struct_list_t{n: 6, next: &C.list_t{n: 7, next: nil}}}
for list != nil {
diff --git a/testdata/cgo/main.h b/testdata/cgo/main.h
index 7f414a844..d38b33229 100644
--- a/testdata/cgo/main.h
+++ b/testdata/cgo/main.h
@@ -43,6 +43,31 @@ typedef struct {
int z;
} point3d_t;
+typedef struct {
+ int tag;
+ union {
+ int a;
+ int b;
+ } u;
+} tagged_union_t;
+
+typedef struct {
+ int x;
+ struct {
+ char red;
+ char green;
+ char blue;
+ } color;
+} nested_struct_t;
+
+typedef union {
+ int x;
+ struct {
+ char a;
+ char b;
+ };
+} nested_union_t;
+
// linked list
typedef struct list_t {
int n;