mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +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
|
|
@ -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…
Add table
Add a link
Reference in a new issue