aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/cgo
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2020-04-30 23:05:51 -0700
committerMatthew Dempsky <mdempsky@google.com>2020-05-01 18:01:28 +0000
commitb565d1ec1630f6ffa50024fe14ac4ea88a2e6701 (patch)
treef6bc8d523567cb92e4b027a22301e6074b5d2086 /src/cmd/cgo
parentf00b8b45a24479836d8c148cf85fd97091290b05 (diff)
downloadgo-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.go15
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" {