diff options
Diffstat (limited to 'libgo/go/cmd/cgo/gcc.go')
-rw-r--r-- | libgo/go/cmd/cgo/gcc.go | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go index 310316b..249cfe4 100644 --- a/libgo/go/cmd/cgo/gcc.go +++ b/libgo/go/cmd/cgo/gcc.go @@ -200,6 +200,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, @@ -351,7 +354,7 @@ func (p *Package) guessKinds(f *File) []*Name { // void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); } // // If we see an error at not-declared:xxx, the corresponding name is not declared. - // If we see an error at not-type:xxx, the corresponding name is a type. + // If we see an error at not-type:xxx, the corresponding name is not a type. // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant. // If we see an error at not-num-const:xxx, the corresponding name is not a number constant. // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal. @@ -728,6 +731,9 @@ func (p *Package) prepareNames(f *File) { } } p.mangleName(n) + if n.Kind == "type" && typedef[n.Mangle] == nil { + typedef[n.Mangle] = n.Type + } } } @@ -1366,6 +1372,9 @@ func (p *Package) rewriteRef(f *File) { if *godefs { // Substitute definition for mangled type name. + if r.Name.Type != nil && r.Name.Kind == "type" { + expr = r.Name.Type.Go + } if id, ok := expr.(*ast.Ident); ok { if t := typedef[id.Name]; t != nil { expr = t.Go @@ -1431,9 +1440,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)) @@ -1490,9 +1497,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": @@ -1511,8 +1516,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" { @@ -2082,6 +2085,10 @@ var goIdent = make(map[string]*ast.Ident) // that may contain a pointer. This is used for cgo pointer checking. var unionWithPointer = make(map[ast.Expr]bool) +// anonymousStructTag provides a consistent tag for an anonymous struct. +// The same dwarf.StructType pointer will always get the same tag. +var anonymousStructTag = make(map[*dwarf.StructType]string) + func (c *typeConv) Init(ptrSize, intSize int64) { c.ptrSize = ptrSize c.intSize = intSize @@ -2430,8 +2437,12 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ break } if tag == "" { - tag = "__" + strconv.Itoa(tagGen) - tagGen++ + tag = anonymousStructTag[dt] + if tag == "" { + tag = "__" + strconv.Itoa(tagGen) + tagGen++ + anonymousStructTag[dt] = tag + } } else if t.C.Empty() { t.C.Set(dt.Kind + " " + tag) } @@ -3028,8 +3039,9 @@ func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool { return ok && st.StructName == "" } -// badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go. -// A typedef is bad if C code sometimes stores non-pointers in this type. +// badPointerTypedef reports whether dt is a C typedef that should not be +// considered a pointer in Go. A typedef is bad if C code sometimes stores +// non-pointers in this type. // TODO: Currently our best solution is to find these manually and list them as // they come up. A better solution is desired. func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool { @@ -3039,7 +3051,7 @@ func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool { if c.badJNI(dt) { return true } - if c.badEGLDisplay(dt) { + if c.badEGLType(dt) { return true } return false @@ -3178,11 +3190,11 @@ func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool { return false } -func (c *typeConv) badEGLDisplay(dt *dwarf.TypedefType) bool { - if dt.Name != "EGLDisplay" { +func (c *typeConv) badEGLType(dt *dwarf.TypedefType) bool { + if dt.Name != "EGLDisplay" && dt.Name != "EGLConfig" { return false } - // Check that the typedef is "typedef void *EGLDisplay". + // Check that the typedef is "typedef void *<name>". if ptr, ok := dt.Type.(*dwarf.PtrType); ok { if _, ok := ptr.Type.(*dwarf.VoidType); ok { return true |