mirror of
https://github.com/golang/go
synced 2024-11-25 10:07:56 -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),
|
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);
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user