cgo: add support for nested structs and unions
Этот коммит содержится в:
родитель
6108ee6859
коммит
b153bd63f2
5 изменённых файлов: 87 добавлений и 12 удалений
|
@ -667,7 +667,13 @@ func tinygo_clang_struct_visitor(c, parent C.GoCXCursor, client_data C.CXClientD
|
||||||
bitfieldNum := passed.bitfieldNum
|
bitfieldNum := passed.bitfieldNum
|
||||||
bitfieldList := passed.bitfieldList
|
bitfieldList := passed.bitfieldList
|
||||||
pos := p.getCursorPosition(c)
|
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))
|
cursorKindSpelling := getString(C.clang_getCursorKindSpelling(cursorKind))
|
||||||
p.addError(pos, fmt.Sprintf("expected FieldDecl in struct or union, not %s", cursorKindSpelling))
|
p.addError(pos, fmt.Sprintf("expected FieldDecl in struct or union, not %s", cursorKindSpelling))
|
||||||
return C.CXChildVisit_Continue
|
return C.CXChildVisit_Continue
|
||||||
|
|
24
cgo/testdata/types.go
предоставленный
24
cgo/testdata/types.go
предоставленный
|
@ -44,7 +44,23 @@ typedef union union2d {
|
||||||
} union2d_t;
|
} union2d_t;
|
||||||
typedef union {
|
typedef union {
|
||||||
unsigned char arr[10];
|
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
|
// Enums. These define constant numbers. All these constants must be given the
|
||||||
// correct number.
|
// correct number.
|
||||||
|
@ -108,7 +124,11 @@ var (
|
||||||
_ C.union1_t
|
_ C.union1_t
|
||||||
_ C.union3_t
|
_ C.union3_t
|
||||||
_ C.union2d_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).
|
// Enums (anonymous and named).
|
||||||
_ C.option_t
|
_ C.option_t
|
||||||
|
|
37
cgo/testdata/types.out.go
предоставленный
37
cgo/testdata/types.out.go
предоставленный
|
@ -34,7 +34,7 @@ type C.uint uint32
|
||||||
type C.ulong uint32
|
type C.ulong uint32
|
||||||
type C.ulonglong uint64
|
type C.ulonglong uint64
|
||||||
type C.ushort uint16
|
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.myIntArray = [10]C.int
|
||||||
type C.myint = C.int
|
type C.myint = C.int
|
||||||
type C.option2_t = C.uint
|
type C.option2_t = C.uint
|
||||||
|
@ -44,6 +44,13 @@ type C.point2d_t = struct {
|
||||||
y C.int
|
y C.int
|
||||||
}
|
}
|
||||||
type C.point3d_t = C.struct_point3d
|
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 {
|
type C.types_t = struct {
|
||||||
f float32
|
f float32
|
||||||
d float64
|
d float64
|
||||||
|
@ -52,22 +59,23 @@ type C.types_t = struct {
|
||||||
type C.union1_t = struct{ i C.int }
|
type C.union1_t = struct{ i C.int }
|
||||||
type C.union2d_t = C.union_union2d
|
type C.union2d_t = C.union_union2d
|
||||||
type C.union3_t = C.union_1
|
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_4) 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_4) 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_b() C.uchar {
|
||||||
return s.__bitfield_1 >> 5 & 0x1
|
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_4) 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) bitfield_c() C.uchar {
|
||||||
return s.__bitfield_1 >> 6
|
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 }
|
) { s.__bitfield_1 = s.__bitfield_1&0x3f | value<<6 }
|
||||||
|
|
||||||
type C.struct_2 struct {
|
type C.struct_4 struct {
|
||||||
start C.uchar
|
start C.uchar
|
||||||
__bitfield_1 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 }
|
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_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)) }
|
func (union *C.union_union2d) unionfield_d() *[2]float64 { return (*[2]float64)(unsafe.Pointer(&union.$union)) }
|
||||||
|
|
||||||
|
|
5
testdata/cgo/main.go
предоставленный
5
testdata/cgo/main.go
предоставленный
|
@ -80,6 +80,11 @@ func main() {
|
||||||
var _ C.point2d_t = C.point2d_t{x: 3, y: 5}
|
var _ C.point2d_t = C.point2d_t{x: 3, y: 5}
|
||||||
var _ C.point3d_t = C.point3d_t{x: 3, y: 5, z: 7}
|
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
|
// 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}}}
|
list := &C.list_t{n: 3, next: &C.struct_list_t{n: 6, next: &C.list_t{n: 7, next: nil}}}
|
||||||
for list != nil {
|
for list != nil {
|
||||||
|
|
25
testdata/cgo/main.h
предоставленный
25
testdata/cgo/main.h
предоставленный
|
@ -43,6 +43,31 @@ typedef struct {
|
||||||
int z;
|
int z;
|
||||||
} point3d_t;
|
} 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
|
// linked list
|
||||||
typedef struct list_t {
|
typedef struct list_t {
|
||||||
int n;
|
int n;
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче