diff options
| author | Ondřej Surý <ondrej@sury.org> | 2012-02-29 11:23:13 +0100 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2012-02-29 11:23:13 +0100 |
| commit | b6d7097a0d6072199f2cd74d67404890697cf78a (patch) | |
| tree | a2193c528a79fd5606507568859ee5067c6b86e4 /src/cmd/cgo/out.go | |
| parent | 4cecda6c347bd6902b960c6a35a967add7070b0d (diff) | |
| download | golang-b6d7097a0d6072199f2cd74d67404890697cf78a.tar.gz | |
Imported Upstream version 2012.02.22upstream-weekly/2012.02.22
Diffstat (limited to 'src/cmd/cgo/out.go')
| -rw-r--r-- | src/cmd/cgo/out.go | 83 |
1 files changed, 58 insertions, 25 deletions
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index 3e25b2099..4dc0f8454 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -17,6 +17,8 @@ import ( "strings" ) +var conf = printer.Config{Mode: printer.SourcePos, Tabwidth: 8} + // writeDefs creates output files to be compiled by 6g, 6c, and gcc. // (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.) func (p *Package) writeDefs() { @@ -57,7 +59,7 @@ func (p *Package) writeDefs() { for name, def := range typedef { fmt.Fprintf(fgo2, "type %s ", name) - printer.Fprint(fgo2, fset, def) + conf.Fprint(fgo2, fset, def.Go) fmt.Fprintf(fgo2, "\n\n") } fmt.Fprintf(fgo2, "type _Ctype_void [0]byte\n") @@ -87,7 +89,7 @@ func (p *Package) writeDefs() { fmt.Fprintf(fc, "\n") fmt.Fprintf(fgo2, "var %s ", n.Mangle) - printer.Fprint(fgo2, fset, &ast.StarExpr{X: n.Type.Go}) + conf.Fprint(fgo2, fset, &ast.StarExpr{X: n.Type.Go}) fmt.Fprintf(fgo2, "\n") } fmt.Fprintf(fc, "\n") @@ -194,7 +196,11 @@ func (p *Package) structType(n *Name) (string, int64) { fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad) off += pad } - fmt.Fprintf(&buf, "\t\t%s p%d;\n", t.C, i) + c := t.Typedef + if c == "" { + c = t.C.String() + } + fmt.Fprintf(&buf, "\t\t%s p%d;\n", c, i) off += t.Size } if off%p.PtrSize != 0 { @@ -255,23 +261,46 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) { Name: ast.NewIdent(n.Mangle), Type: gtype, } - printer.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) @@ -327,8 +356,7 @@ func (p *Package) writeOutput(f *File, srcfile string) { // Write Go output: Go input with rewrites of C.xxx to _C_xxx. fmt.Fprintf(fgo1, "// Created by cgo - DO NOT EDIT\n\n") - fmt.Fprintf(fgo1, "//line %s:1\n", srcfile) - printer.Fprint(fgo1, fset, f.AST) + conf.Fprint(fgo1, fset, f.AST) // While we process the vars and funcs, also write 6c and gcc output. // Gcc output starts with the preamble. @@ -354,6 +382,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 @@ -399,6 +432,7 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) { fgcch := creat(*objDir + "_cgo_export.h") fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n") + fmt.Fprintf(fgcch, "%s\n", p.Preamble) fmt.Fprintf(fgcch, "%s\n", gccExportHeaderProlog) fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n") @@ -542,11 +576,11 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) { // a Go wrapper function. if fn.Recv != nil { fmt.Fprintf(fgo2, "func %s(recv ", goname) - printer.Fprint(fgo2, fset, fn.Recv.List[0].Type) + conf.Fprint(fgo2, fset, fn.Recv.List[0].Type) forFieldList(fntype.Params, func(i int, atype ast.Expr) { fmt.Fprintf(fgo2, ", p%d ", i) - printer.Fprint(fgo2, fset, atype) + conf.Fprint(fgo2, fset, atype) }) fmt.Fprintf(fgo2, ")") if gccResult != "void" { @@ -556,7 +590,7 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) { if i > 0 { fmt.Fprint(fgo2, ", ") } - printer.Fprint(fgo2, fset, atype) + conf.Fprint(fgo2, fset, atype) }) fmt.Fprint(fgo2, ")") } @@ -664,10 +698,8 @@ func (p *Package) cgoType(e ast.Expr) *Type { } } } - for name, def := range typedef { - if name == t.Name { - return p.cgoType(def) - } + if def := typedef[t.Name]; def != nil { + return def } if t.Name == "uintptr" { return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("uintptr")} @@ -692,7 +724,7 @@ func (p *Package) cgoType(e ast.Expr) *Type { return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*")} } } - error_(e.Pos(), "unrecognized Go type %T", e) + error_(e.Pos(), "Go type not supported in export: %s", gofmt(e)) return &Type{Size: 4, Align: 4, C: c("int")} } @@ -782,11 +814,12 @@ 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) { - return __go_byte_array_to_string(p, strlen(p)); + int len = (p != NULL) ? strlen(p) : 0; + return __go_byte_array_to_string(p, len); } struct __go_string GoStringN(char *p, int n) { @@ -794,7 +827,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); } ` |
