1
0
mirror of https://github.com/golang/go synced 2024-11-21 23:14:40 -07:00

cgo: add support for returning errno with gccgo.

Also eliminate some warnings in builds.

R=golang-dev, fullung, iant, rsc
CC=golang-dev, remy
https://golang.org/cl/5650066
This commit is contained in:
Rémy Oudompheng 2012-02-14 20:23:45 +01:00
parent 9f8c2c8bbf
commit f8f0a2bc7b
2 changed files with 46 additions and 15 deletions

View File

@ -257,23 +257,46 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
Name: ast.NewIdent(n.Mangle), Name: ast.NewIdent(n.Mangle),
Type: gtype, Type: gtype,
} }
conf.Fprint(fgo2, fset, d)
if *gccgo { if *gccgo {
fmt.Fprintf(fgo2, " __asm__(\"%s\")\n", n.C) // Gccgo style hooks.
} else { // we hook directly into C. gccgo goes not support cgocall yet.
fmt.Fprintf(fgo2, "\n") if !n.AddError {
fmt.Fprintf(fgo2, "//extern %s\n", n.C)
conf.Fprint(fgo2, fset, d)
fmt.Fprint(fgo2, "\n")
} else {
// write a small wrapper to retrieve errno.
cname := fmt.Sprintf("_cgo%s%s", cPrefix, n.Mangle)
paramnames := []string(nil)
for i, param := range d.Type.Params.List {
paramName := fmt.Sprintf("p%d", i)
param.Names = []*ast.Ident{ast.NewIdent(paramName)}
paramnames = append(paramnames, paramName)
}
conf.Fprint(fgo2, fset, d)
fmt.Fprintf(fgo2, "{\n")
fmt.Fprintf(fgo2, "\tr := %s(%s)\n", cname, strings.Join(paramnames, ", "))
fmt.Fprintf(fgo2, "\treturn r, syscall.GetErrno()\n")
fmt.Fprintf(fgo2, "}\n")
// declare the C function.
fmt.Fprintf(fgo2, "//extern %s\n", n.C)
d.Name = ast.NewIdent(cname)
l := d.Type.Results.List
d.Type.Results.List = l[:len(l)-1]
conf.Fprint(fgo2, fset, d)
fmt.Fprint(fgo2, "\n")
}
return
} }
conf.Fprint(fgo2, fset, d)
fmt.Fprint(fgo2, "\n")
if name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes" { if name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes" {
// The builtins are already defined in the C prolog. // The builtins are already defined in the C prolog.
return return
} }
// gccgo does not require a wrapper unless an error must be returned.
if *gccgo && !n.AddError {
return
}
var argSize int64 var argSize int64
_, argSize = p.structType(n) _, argSize = p.structType(n)
@ -355,6 +378,11 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
} }
p.Written[name] = true p.Written[name] = true
if *gccgo {
// we don't use wrappers with gccgo.
return
}
ctype, _ := p.structType(n) ctype, _ := p.structType(n)
// Gcc wrapper unpacks the C argument struct // Gcc wrapper unpacks the C argument struct
@ -783,7 +811,7 @@ struct __go_string __go_byte_array_to_string(const void* p, int len);
struct __go_open_array __go_string_to_byte_array (struct __go_string str); struct __go_open_array __go_string_to_byte_array (struct __go_string str);
const char *CString(struct __go_string s) { const char *CString(struct __go_string s) {
return strndup(s.__data, s.__length); return strndup((const char*)s.__data, s.__length);
} }
struct __go_string GoString(char *p) { struct __go_string GoString(char *p) {
@ -796,7 +824,7 @@ struct __go_string GoStringN(char *p, int n) {
} }
Slice GoBytes(char *p, int n) { Slice GoBytes(char *p, int n) {
struct __go_string s = { p, n }; struct __go_string s = { (const unsigned char *)p, n };
return __go_string_to_byte_array(s); return __go_string_to_byte_array(s);
} }
` `

View File

@ -1152,8 +1152,6 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
return nil, nil, errors.New("cannot use cgo when compiling for a different operating system") return nil, nil, errors.New("cannot use cgo when compiling for a different operating system")
} }
outObj = append(outObj, "") // for importObj, at end of function
cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.info.CgoCFLAGS) cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.info.CgoCFLAGS)
cgoLDFLAGS := stringList(envList("CGO_LDFLAGS"), p.info.CgoLDFLAGS) cgoLDFLAGS := stringList(envList("CGO_LDFLAGS"), p.info.CgoLDFLAGS)
@ -1238,6 +1236,11 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
return nil, nil, err return nil, nil, err
} }
if _, ok := buildToolchain.(gccgoToolchain); ok {
// we don't use dynimport when using gccgo.
return outGo, outObj, nil
}
// cgo -dynimport // cgo -dynimport
importC := obj + "_cgo_import.c" importC := obj + "_cgo_import.c"
if err := b.run(p.Dir, p.ImportPath, cgoExe, "-objdir", obj, "-dynimport", dynobj, "-dynout", importC); err != nil { if err := b.run(p.Dir, p.ImportPath, cgoExe, "-objdir", obj, "-dynimport", dynobj, "-dynout", importC); err != nil {
@ -1252,8 +1255,8 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
// NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows // NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
// must be processed before the gcc-generated objects. // must be processed before the gcc-generated objects.
// Put it first. We left room above. http://golang.org/issue/2601 // Put it first. http://golang.org/issue/2601
outObj[0] = importObj outObj = append([]string{importObj}, outObj...)
return outGo, outObj, nil return outGo, outObj, nil
} }