mirror of
https://github.com/golang/go
synced 2024-11-12 03:50:21 -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:
parent
9f8c2c8bbf
commit
f8f0a2bc7b
@ -257,23 +257,46 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
||||
Name: ast.NewIdent(n.Mangle),
|
||||
Type: gtype,
|
||||
}
|
||||
conf.Fprint(fgo2, fset, d)
|
||||
|
||||
if *gccgo {
|
||||
fmt.Fprintf(fgo2, " __asm__(\"%s\")\n", n.C)
|
||||
} else {
|
||||
fmt.Fprintf(fgo2, "\n")
|
||||
// Gccgo style hooks.
|
||||
// we hook directly into C. gccgo goes not support cgocall yet.
|
||||
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" {
|
||||
// The builtins are already defined in the C prolog.
|
||||
return
|
||||
}
|
||||
|
||||
// gccgo does not require a wrapper unless an error must be returned.
|
||||
if *gccgo && !n.AddError {
|
||||
return
|
||||
}
|
||||
|
||||
var argSize int64
|
||||
_, argSize = p.structType(n)
|
||||
|
||||
@ -355,6 +378,11 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
|
||||
}
|
||||
p.Written[name] = true
|
||||
|
||||
if *gccgo {
|
||||
// we don't use wrappers with gccgo.
|
||||
return
|
||||
}
|
||||
|
||||
ctype, _ := p.structType(n)
|
||||
|
||||
// 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);
|
||||
|
||||
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) {
|
||||
@ -796,7 +824,7 @@ struct __go_string GoStringN(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);
|
||||
}
|
||||
`
|
||||
|
@ -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")
|
||||
}
|
||||
|
||||
outObj = append(outObj, "") // for importObj, at end of function
|
||||
|
||||
cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.info.CgoCFLAGS)
|
||||
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
|
||||
}
|
||||
|
||||
if _, ok := buildToolchain.(gccgoToolchain); ok {
|
||||
// we don't use dynimport when using gccgo.
|
||||
return outGo, outObj, nil
|
||||
}
|
||||
|
||||
// cgo -dynimport
|
||||
importC := obj + "_cgo_import.c"
|
||||
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
|
||||
// must be processed before the gcc-generated objects.
|
||||
// Put it first. We left room above. http://golang.org/issue/2601
|
||||
outObj[0] = importObj
|
||||
// Put it first. http://golang.org/issue/2601
|
||||
outObj = append([]string{importObj}, outObj...)
|
||||
|
||||
return outGo, outObj, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user