Browse Source

cgo: add support for nested structs and unions

pull/98/head
Ayke van Laethem 5 years ago
committed by Ron Evans
parent
commit
b153bd63f2
  1. 8
      cgo/libclang.go
  2. 24
      cgo/testdata/types.go
  3. 37
      cgo/testdata/types.out.go
  4. 5
      testdata/cgo/main.go
  5. 25
      testdata/cgo/main.h

8
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

24
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

37
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)) }

5
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 {

25
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;

Loading…
Cancel
Save