mirror of
https://github.com/golang/go
synced 2024-10-06 16:10:03 +00:00
cmd/cgo: consistently map void* to *byte under -{c,go}defs
Fixes #8478. LGTM=iant R=iant CC=golang-codereviews https://golang.org/cl/122150043
This commit is contained in:
parent
7dfcebbd2d
commit
2b9f3fcead
20
misc/cgo/testgodefs/issue8478.go
Normal file
20
misc/cgo/testgodefs/issue8478.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
// Issue 8478. Test that void* is consistently mapped to *byte.
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef struct {
|
||||||
|
void *p;
|
||||||
|
void **q;
|
||||||
|
void ***r;
|
||||||
|
} s;
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
type Issue8478 C.s
|
|
@ -8,5 +8,8 @@ package main
|
||||||
var v1 T
|
var v1 T
|
||||||
var v2 = v1.L
|
var v2 = v1.L
|
||||||
|
|
||||||
|
// Test that P, Q, and R all point to byte.
|
||||||
|
var v3 = Issue8478{P: (*byte)(nil), Q: (**byte)(nil), R: (***byte)(nil)}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
# We are testing cgo -godefs, which translates Go files that use
|
# We are testing cgo -godefs, which translates Go files that use
|
||||||
# import "C" into Go files with Go definitions of types defined in the
|
# import "C" into Go files with Go definitions of types defined in the
|
||||||
# import "C" block. Add more tests here.
|
# import "C" block. Add more tests here.
|
||||||
FILE_PREFIXES="anonunion"
|
FILE_PREFIXES="anonunion issue8478"
|
||||||
|
|
||||||
RM=
|
RM=
|
||||||
for FP in $FILE_PREFIXES
|
for FP in $FILE_PREFIXES
|
||||||
|
|
|
@ -929,9 +929,6 @@ type typeConv struct {
|
||||||
// Map from types to incomplete pointers to those types.
|
// Map from types to incomplete pointers to those types.
|
||||||
ptrs map[dwarf.Type][]*Type
|
ptrs map[dwarf.Type][]*Type
|
||||||
|
|
||||||
// Fields to be processed by godefsField after completing pointers.
|
|
||||||
todoFlds [][]*ast.Field
|
|
||||||
|
|
||||||
// Predeclared types.
|
// Predeclared types.
|
||||||
bool ast.Expr
|
bool ast.Expr
|
||||||
byte ast.Expr // denotes padding
|
byte ast.Expr // denotes padding
|
||||||
|
@ -940,9 +937,9 @@ type typeConv struct {
|
||||||
float32, float64 ast.Expr
|
float32, float64 ast.Expr
|
||||||
complex64, complex128 ast.Expr
|
complex64, complex128 ast.Expr
|
||||||
void ast.Expr
|
void ast.Expr
|
||||||
unsafePointer ast.Expr
|
|
||||||
string ast.Expr
|
string ast.Expr
|
||||||
goVoid ast.Expr // _Ctype_void, denotes C's void
|
goVoid ast.Expr // _Ctype_void, denotes C's void
|
||||||
|
goVoidPtr ast.Expr // unsafe.Pointer or *byte
|
||||||
|
|
||||||
ptrSize int64
|
ptrSize int64
|
||||||
intSize int64
|
intSize int64
|
||||||
|
@ -972,10 +969,17 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
|
||||||
c.float64 = c.Ident("float64")
|
c.float64 = c.Ident("float64")
|
||||||
c.complex64 = c.Ident("complex64")
|
c.complex64 = c.Ident("complex64")
|
||||||
c.complex128 = c.Ident("complex128")
|
c.complex128 = c.Ident("complex128")
|
||||||
c.unsafePointer = c.Ident("unsafe.Pointer")
|
|
||||||
c.void = c.Ident("void")
|
c.void = c.Ident("void")
|
||||||
c.string = c.Ident("string")
|
c.string = c.Ident("string")
|
||||||
c.goVoid = c.Ident("_Ctype_void")
|
c.goVoid = c.Ident("_Ctype_void")
|
||||||
|
|
||||||
|
// Normally cgo translates void* to unsafe.Pointer,
|
||||||
|
// but for historical reasons -cdefs and -godefs use *byte instead.
|
||||||
|
if *cdefs || *godefs {
|
||||||
|
c.goVoidPtr = &ast.StarExpr{X: c.byte}
|
||||||
|
} else {
|
||||||
|
c.goVoidPtr = c.Ident("unsafe.Pointer")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// base strips away qualifiers and typedefs to get the underlying type
|
// base strips away qualifiers and typedefs to get the underlying type
|
||||||
|
@ -1037,8 +1041,7 @@ func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinishType completes any outstanding type mapping work.
|
// FinishType completes any outstanding type mapping work.
|
||||||
// In particular, it resolves incomplete pointer types and also runs
|
// In particular, it resolves incomplete pointer types.
|
||||||
// godefsFields on any new struct types.
|
|
||||||
func (c *typeConv) FinishType(pos token.Pos) {
|
func (c *typeConv) FinishType(pos token.Pos) {
|
||||||
// Completing one pointer type might produce more to complete.
|
// Completing one pointer type might produce more to complete.
|
||||||
// Keep looping until they're all done.
|
// Keep looping until they're all done.
|
||||||
|
@ -1053,13 +1056,6 @@ func (c *typeConv) FinishType(pos token.Pos) {
|
||||||
delete(c.ptrs, dtype)
|
delete(c.ptrs, dtype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that pointer types are completed, we can invoke godefsFields
|
|
||||||
// to rewrite struct definitions.
|
|
||||||
for _, fld := range c.todoFlds {
|
|
||||||
godefsFields(fld)
|
|
||||||
}
|
|
||||||
c.todoFlds = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type returns a *Type with the same memory layout as
|
// Type returns a *Type with the same memory layout as
|
||||||
|
@ -1209,9 +1205,8 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
case *dwarf.PtrType:
|
case *dwarf.PtrType:
|
||||||
t.Align = c.ptrSize
|
t.Align = c.ptrSize
|
||||||
|
|
||||||
// Translate void* as unsafe.Pointer
|
|
||||||
if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
|
if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
|
||||||
t.Go = c.unsafePointer
|
t.Go = c.goVoidPtr
|
||||||
t.C.Set("void*")
|
t.C.Set("void*")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1656,7 +1651,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
||||||
csyntax = buf.String()
|
csyntax = buf.String()
|
||||||
|
|
||||||
if *godefs || *cdefs {
|
if *godefs || *cdefs {
|
||||||
c.todoFlds = append(c.todoFlds, fld)
|
godefsFields(fld)
|
||||||
}
|
}
|
||||||
expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
|
expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
|
||||||
return
|
return
|
||||||
|
@ -1694,19 +1689,6 @@ func godefsFields(fld []*ast.Field) {
|
||||||
n.Name = upper(n.Name)
|
n.Name = upper(n.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p := &f.Type
|
|
||||||
t := *p
|
|
||||||
if star, ok := t.(*ast.StarExpr); ok {
|
|
||||||
star = &ast.StarExpr{X: star.X}
|
|
||||||
*p = star
|
|
||||||
p = &star.X
|
|
||||||
t = *p
|
|
||||||
}
|
|
||||||
if id, ok := t.(*ast.Ident); ok {
|
|
||||||
if id.Name == "unsafe.Pointer" {
|
|
||||||
*p = ast.NewIdent("*byte")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue