diff options
author | Matthew Dempsky <mdempsky@google.com> | 2020-04-30 23:05:51 -0700 |
---|---|---|
committer | Matthew Dempsky <mdempsky@google.com> | 2020-05-01 18:01:28 +0000 |
commit | b565d1ec1630f6ffa50024fe14ac4ea88a2e6701 (patch) | |
tree | f6bc8d523567cb92e4b027a22301e6074b5d2086 /src/cmd/cgo | |
parent | f00b8b45a24479836d8c148cf85fd97091290b05 (diff) | |
download | go-b565d1ec1630f6ffa50024fe14ac4ea88a2e6701.tar.gz go-b565d1ec1630f6ffa50024fe14ac4ea88a2e6701.zip |
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>
Diffstat (limited to 'src/cmd/cgo')
-rw-r--r-- | src/cmd/cgo/gcc.go | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go index e01ea081d9..39ab5788ec 100644 --- a/src/cmd/cgo/gcc.go +++ b/src/cmd/cgo/gcc.go @@ -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" { |