mirror of
https://github.com/golang/go
synced 2024-11-02 11:50:30 +00:00
cmd/cgo: use type aliases for #define type macros
Cgo's initial design for handling "#define foo int*" involved rewriting "C.foo" to "*_Ctype_int" everywhere. But now that we have type aliases, we can declare "type _Ctype_foo = *_Ctype_int" once, and then rewrite "C.foo" to just "_Ctype_foo". This is important for go/types's UsesCgo mode, where go/types needs to be able to figure out a type for each C.foo identifier using only the information written into _cgo_gotypes.go. Fixes #38649. Change-Id: Ia0f8c2d82df81efb1be5bc26195ea9154c0af871 Reviewed-on: https://go-review.googlesource.com/c/go/+/230037 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
f00b8b45a2
commit
b565d1ec16
5 changed files with 36 additions and 6 deletions
|
@ -897,6 +897,10 @@ static uint16_t issue31093F(uint16_t v) { return v; }
|
|||
|
||||
// issue 32579
|
||||
typedef struct S32579 { unsigned char data[1]; } S32579;
|
||||
|
||||
// issue 38649
|
||||
// Test that #define'd type aliases work.
|
||||
#define netbsd_gid unsigned int
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
@ -2192,3 +2196,7 @@ func test32579(t *testing.T) {
|
|||
t.Errorf("&s[0].data[0] failed: got %d, want %d", s[0].data[0], 1)
|
||||
}
|
||||
}
|
||||
|
||||
// issue 38649
|
||||
|
||||
var issue38649 C.netbsd_gid = 42
|
||||
|
|
15
misc/cgo/testgodefs/testdata/issue38649.go
vendored
Normal file
15
misc/cgo/testgodefs/testdata/issue38649.go
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2020 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
|
||||
|
||||
/*
|
||||
struct Issue38649 { int x; };
|
||||
#define issue38649 struct Issue38649
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type issue38649 C.issue38649
|
3
misc/cgo/testgodefs/testdata/main.go
vendored
3
misc/cgo/testgodefs/testdata/main.go
vendored
|
@ -19,5 +19,8 @@ var v6 = B{}
|
|||
// Test that S is fully defined
|
||||
var v7 = S{}
|
||||
|
||||
// Test that #define'd type is fully defined
|
||||
var _ = issue38649{X: 0}
|
||||
|
||||
func main() {
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ var filePrefixes = []string{
|
|||
"fieldtypedef",
|
||||
"issue37479",
|
||||
"issue37621",
|
||||
"issue38649",
|
||||
}
|
||||
|
||||
func TestGoDefs(t *testing.T) {
|
||||
|
|
|
@ -182,6 +182,9 @@ func (p *Package) Translate(f *File) {
|
|||
numTypedefs = len(p.typedefs)
|
||||
// Also ask about any typedefs we've seen so far.
|
||||
for _, info := range p.typedefList {
|
||||
if f.Name[info.typedef] != nil {
|
||||
continue
|
||||
}
|
||||
n := &Name{
|
||||
Go: info.typedef,
|
||||
C: info.typedef,
|
||||
|
@ -710,6 +713,9 @@ func (p *Package) prepareNames(f *File) {
|
|||
}
|
||||
}
|
||||
p.mangleName(n)
|
||||
if n.Kind == "type" && typedef[n.Mangle] == nil {
|
||||
typedef[n.Mangle] = n.Type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1348,6 +1354,9 @@ func (p *Package) rewriteRef(f *File) {
|
|||
|
||||
if *godefs {
|
||||
// Substitute definition for mangled type name.
|
||||
if r.Name.Type != nil {
|
||||
expr = r.Name.Type.Go
|
||||
}
|
||||
if id, ok := expr.(*ast.Ident); ok {
|
||||
if t := typedef[id.Name]; t != nil {
|
||||
expr = t.Go
|
||||
|
@ -1413,9 +1422,7 @@ func (p *Package) rewriteName(f *File, r *Ref) ast.Expr {
|
|||
r.Context = ctxType
|
||||
if r.Name.Type == nil {
|
||||
error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
|
||||
break
|
||||
}
|
||||
expr = r.Name.Type.Go
|
||||
break
|
||||
}
|
||||
error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
|
||||
|
@ -1472,9 +1479,7 @@ func (p *Package) rewriteName(f *File, r *Ref) ast.Expr {
|
|||
// Okay - might be new(T)
|
||||
if r.Name.Type == nil {
|
||||
error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
|
||||
break
|
||||
}
|
||||
expr = r.Name.Type.Go
|
||||
case "var":
|
||||
expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
|
||||
case "macro":
|
||||
|
@ -1493,8 +1498,6 @@ func (p *Package) rewriteName(f *File, r *Ref) ast.Expr {
|
|||
// Use of C.enum_x, C.struct_x or C.union_x without C definition.
|
||||
// GCC won't raise an error when using pointers to such unknown types.
|
||||
error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
|
||||
} else {
|
||||
expr = r.Name.Type.Go
|
||||
}
|
||||
default:
|
||||
if r.Name.Kind == "func" {
|
||||
|
|
Loading…
Reference in a new issue