mirror of
https://github.com/golang/go
synced 2024-11-20 05:44:44 -07:00
cmd/cgo: prepare for 64-bit ints
This CL makes the size of an int controlled by a variable in cgo instead of hard-coding 4 (or 32 bits) in various places. Update #2188. R=iant, r, dave CC=golang-dev https://golang.org/cl/6548061
This commit is contained in:
parent
0a006b4923
commit
5501a097a9
@ -601,7 +601,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
|
||||
|
||||
// Record types and typedef information.
|
||||
var conv typeConv
|
||||
conv.Init(p.PtrSize)
|
||||
conv.Init(p.PtrSize, p.IntSize)
|
||||
for i, n := range names {
|
||||
if types[i] == nil {
|
||||
continue
|
||||
@ -928,14 +928,16 @@ type typeConv struct {
|
||||
string ast.Expr
|
||||
|
||||
ptrSize int64
|
||||
intSize int64
|
||||
}
|
||||
|
||||
var tagGen int
|
||||
var typedef = make(map[string]*Type)
|
||||
var goIdent = make(map[string]*ast.Ident)
|
||||
|
||||
func (c *typeConv) Init(ptrSize int64) {
|
||||
func (c *typeConv) Init(ptrSize, intSize int64) {
|
||||
c.ptrSize = ptrSize
|
||||
c.intSize = intSize
|
||||
c.m = make(map[dwarf.Type]*Type)
|
||||
c.bool = c.Ident("bool")
|
||||
c.byte = c.Ident("byte")
|
||||
|
@ -31,6 +31,7 @@ type Package struct {
|
||||
PackageName string // name of package
|
||||
PackagePath string
|
||||
PtrSize int64
|
||||
IntSize int64
|
||||
GccOptions []string
|
||||
CgoFlags map[string]string // #cgo flags (CFLAGS, LDFLAGS)
|
||||
Written map[string]bool
|
||||
@ -129,6 +130,12 @@ var ptrSizeMap = map[string]int64{
|
||||
"arm": 4,
|
||||
}
|
||||
|
||||
var intSizeMap = map[string]int64{
|
||||
"386": 4,
|
||||
"amd64": 4,
|
||||
"arm": 4,
|
||||
}
|
||||
|
||||
var cPrefix string
|
||||
|
||||
var fset = token.NewFileSet()
|
||||
@ -289,7 +296,11 @@ func newPackage(args []string) *Package {
|
||||
}
|
||||
ptrSize := ptrSizeMap[goarch]
|
||||
if ptrSize == 0 {
|
||||
fatalf("unknown $GOARCH %q", goarch)
|
||||
fatalf("unknown ptrSize for $GOARCH %q", goarch)
|
||||
}
|
||||
intSize := intSizeMap[goarch]
|
||||
if intSize == 0 {
|
||||
fatalf("unknown intSize for $GOARCH %q", goarch)
|
||||
}
|
||||
|
||||
// Reset locale variables so gcc emits English errors [sic].
|
||||
@ -298,6 +309,7 @@ func newPackage(args []string) *Package {
|
||||
|
||||
p := &Package{
|
||||
PtrSize: ptrSize,
|
||||
IntSize: intSize,
|
||||
GccOptions: gccOptions,
|
||||
CgoFlags: make(map[string]string),
|
||||
Written: make(map[string]bool),
|
||||
|
@ -59,7 +59,7 @@ func (p *Package) writeDefs() {
|
||||
}
|
||||
fmt.Fprintf(fgo2, "type _ unsafe.Pointer\n\n")
|
||||
if *importSyscall {
|
||||
fmt.Fprintf(fgo2, "func _Cerrno(dst *error, x int) { *dst = syscall.Errno(x) }\n")
|
||||
fmt.Fprintf(fgo2, "func _Cerrno(dst *error, x int32) { *dst = syscall.Errno(x) }\n")
|
||||
}
|
||||
|
||||
typedefNames := make([]string, 0, len(typedef))
|
||||
@ -473,7 +473,7 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
|
||||
|
||||
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(fgcch, "%s\n", p.gccExportHeaderProlog())
|
||||
|
||||
fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n")
|
||||
fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n")
|
||||
@ -664,7 +664,7 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
|
||||
|
||||
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(fgcch, "%s\n", p.gccExportHeaderProlog())
|
||||
fmt.Fprintf(fm, "#include \"_cgo_export.h\"\n")
|
||||
|
||||
clean := func(r rune) rune {
|
||||
@ -775,8 +775,8 @@ func c(repr string, args ...interface{}) *TypeRepr {
|
||||
var goTypes = map[string]*Type{
|
||||
"bool": {Size: 1, Align: 1, C: c("GoUint8")},
|
||||
"byte": {Size: 1, Align: 1, C: c("GoUint8")},
|
||||
"int": {Size: 4, Align: 4, C: c("GoInt")},
|
||||
"uint": {Size: 4, Align: 4, C: c("GoUint")},
|
||||
"int": {Size: 0, Align: 0, C: c("GoInt")},
|
||||
"uint": {Size: 0, Align: 0, C: c("GoUint")},
|
||||
"rune": {Size: 4, Align: 4, C: c("GoInt32")},
|
||||
"int8": {Size: 1, Align: 1, C: c("GoInt8")},
|
||||
"uint8": {Size: 1, Align: 1, C: c("GoUint8")},
|
||||
@ -837,12 +837,21 @@ func (p *Package) cgoType(e ast.Expr) *Type {
|
||||
return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("GoUintptr")}
|
||||
}
|
||||
if t.Name == "string" {
|
||||
return &Type{Size: p.PtrSize + 4, Align: p.PtrSize, C: c("GoString")}
|
||||
// The string data is 1 pointer + 1 int, but this always
|
||||
// rounds to 2 pointers due to alignment.
|
||||
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoString")}
|
||||
}
|
||||
if t.Name == "error" {
|
||||
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
|
||||
}
|
||||
if r, ok := goTypes[t.Name]; ok {
|
||||
if r.Size == 0 { // int or uint
|
||||
rr := new(Type)
|
||||
*rr = *r
|
||||
rr.Size = p.IntSize
|
||||
rr.Align = p.IntSize
|
||||
r = rr
|
||||
}
|
||||
if r.Align > p.PtrSize {
|
||||
r.Align = p.PtrSize
|
||||
}
|
||||
@ -964,9 +973,11 @@ Slice GoBytes(char *p, int n) {
|
||||
}
|
||||
`
|
||||
|
||||
func (p *Package) gccExportHeaderProlog() string {
|
||||
return strings.Replace(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize), -1)
|
||||
}
|
||||
|
||||
const gccExportHeaderProlog = `
|
||||
typedef int GoInt;
|
||||
typedef unsigned int GoUint;
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
@ -975,6 +986,8 @@ typedef int GoInt32;
|
||||
typedef unsigned int GoUint32;
|
||||
typedef long long GoInt64;
|
||||
typedef unsigned long long GoUint64;
|
||||
typedef GoIntGOINTBITS GoInt;
|
||||
typedef GoUintGOINTBITS GoUint;
|
||||
typedef __SIZE_TYPE__ GoUintptr;
|
||||
typedef float GoFloat32;
|
||||
typedef double GoFloat64;
|
||||
|
Loading…
Reference in New Issue
Block a user