mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: remove obsolete -cdefs flag
Now that there's no 6c compiler anymore, there's no need for cgo to generate C headers that are compatible with it. Fixes #9528 Change-Id: I43f53869719eb9a6065f1b39f66f060e604cbee0 Reviewed-on: https://go-review.googlesource.com/2482 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
f7e43f14d3
commit
b2aab72d9a
10 changed files with 16 additions and 387 deletions
|
|
@ -1,9 +0,0 @@
|
||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "runtime.h"
|
|
||||||
#include "cdefstest.h"
|
|
||||||
|
|
||||||
struct CdefsTest test;
|
|
||||||
struct PackedTest packed;
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
//
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package cgotest
|
|
||||||
|
|
||||||
/*
|
|
||||||
// This file tests a bug found in the cgo -cdefs tool that incorrectly
|
|
||||||
// translated Go pointer arrays generated by the cgo godefs tool back into C
|
|
||||||
// pointer arrays.
|
|
||||||
//
|
|
||||||
// The comments below show how the type is translated from gcc-style C into Go
|
|
||||||
// and back into C for both the buggy version and the correct version
|
|
||||||
|
|
||||||
struct cdefsTest {
|
|
||||||
// This was already being handled correctly
|
|
||||||
// Correct: -> Array [20]int8 -> int8 array[20]
|
|
||||||
char array1[20];
|
|
||||||
|
|
||||||
// Buggy: -> Array [20][20]int8 -> [20]int8 array[20]
|
|
||||||
// Correct: -> Array [20][20]int8 -> int8 array[20][20]
|
|
||||||
char array2[20][20];
|
|
||||||
|
|
||||||
// Buggy: -> Array [20]*int8 -> *int8 array[20]
|
|
||||||
// Correct: -> Array [20]*int8 -> int8 *array[20]
|
|
||||||
char *array3[20];
|
|
||||||
|
|
||||||
// Buggy: -> Array [20][20]*int8 -> [20]*int8 array[20]
|
|
||||||
// Correct: -> Array [20]**int8 -> int8 *array[20][20]
|
|
||||||
char *array4[20][20];
|
|
||||||
|
|
||||||
// Buggy: -> Array [20][20]**int8 -> [20]**int8 array[20]
|
|
||||||
// Correct: -> Array [20][20]**int8 -> int8 **array[20][20]
|
|
||||||
char **array5[20][20];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test that packed structures can be translated to C correctly too.
|
|
||||||
// See issue 8477.
|
|
||||||
|
|
||||||
struct packedTest {
|
|
||||||
char first;
|
|
||||||
int second;
|
|
||||||
long long third;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
// Test that conflicting type definitions don't cause problems with cgo.
|
|
||||||
// See issue 8477.
|
|
||||||
|
|
||||||
typedef struct timespec {
|
|
||||||
double bogus;
|
|
||||||
} pid_t;
|
|
||||||
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
type CdefsTest C.struct_cdefsTest
|
|
||||||
|
|
||||||
//type PackedTest C.struct_packedTest
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "runtime.h"
|
|
||||||
#include "cdefstest.h"
|
|
||||||
|
|
||||||
void runtime·printf(int8*, ...);
|
|
||||||
|
|
||||||
// From cdefstest.go.
|
|
||||||
typedef struct CdefsOrig CdefsOrig;
|
|
||||||
struct CdefsOrig {
|
|
||||||
int8 array1[20];
|
|
||||||
int8 array2[20][20];
|
|
||||||
int8 *array3[20];
|
|
||||||
int8 *array4[20][20];
|
|
||||||
int8 **array5[20][20];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Packed structs are no longer supported for -cdefs.
|
|
||||||
/*
|
|
||||||
typedef struct PackedOrig PackedOrig;
|
|
||||||
#pragma pack on
|
|
||||||
struct PackedOrig {
|
|
||||||
int8 first;
|
|
||||||
int32 second;
|
|
||||||
int64 third;
|
|
||||||
};
|
|
||||||
#pragma pack off
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
main·test(int32 ret)
|
|
||||||
{
|
|
||||||
CdefsOrig o;
|
|
||||||
CdefsTest t;
|
|
||||||
// PackedOrig po;
|
|
||||||
// PackedTest pt;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
if(sizeof(t.array1) != sizeof(o.array1) || offsetof(CdefsTest, array1[0]) != offsetof(CdefsOrig, array1[0])) {
|
|
||||||
runtime·printf("array1: size, offset = %d, %d, want %d, %d\n", sizeof(t.array1), offsetof(CdefsTest, array1[0]), sizeof(o.array1), offsetof(CdefsOrig, array1[0]));
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
if(sizeof(t.array2) != sizeof(o.array2) || offsetof(CdefsTest, array2[0][0]) != offsetof(CdefsOrig, array2[0][0])) {
|
|
||||||
runtime·printf("array2: size, offset = %d, %d, want %d, %d\n", sizeof(t.array2), offsetof(CdefsTest, array2[0][0]), sizeof(o.array2), offsetof(CdefsOrig, array2[0][0]));
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
if(sizeof(t.array3) != sizeof(o.array3) || offsetof(CdefsTest, array3[0]) != offsetof(CdefsOrig, array3[0])) {
|
|
||||||
runtime·printf("array3: size, offset = %d, %d, want %d, %d\n", sizeof(t.array3), offsetof(CdefsTest, array3[0]), sizeof(o.array3), offsetof(CdefsOrig, array3[0]));
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
if(sizeof(t.array4) != sizeof(o.array4) || offsetof(CdefsTest, array4[0][0]) != offsetof(CdefsOrig, array4[0][0])) {
|
|
||||||
runtime·printf("array4: size, offset = %d, %d, want %d, %d\n", sizeof(t.array4), offsetof(CdefsTest, array4[0][0]), sizeof(o.array4), offsetof(CdefsOrig, array4[0][0]));
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
if(sizeof(t.array5) != sizeof(o.array5) || offsetof(CdefsTest, array5[0][0]) != offsetof(CdefsOrig, array5[0][0])) {
|
|
||||||
runtime·printf("array5: size, offset = %d, %d, want %d, %d\n", sizeof(t.array5), offsetof(CdefsTest, array5[0][0]), sizeof(o.array5), offsetof(CdefsOrig, array5[0][0]));
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if(sizeof(pt.first) != sizeof(po.first) || offsetof(PackedTest, first) != offsetof(PackedOrig, first)) {
|
|
||||||
runtime·printf("first: size, offset = %d, %d, want %d, %d\n", sizeof(pt.first), offsetof(PackedTest, first), sizeof(po.first), offsetof(PackedOrig, first));
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
if(sizeof(pt.second) != sizeof(po.second) || offsetof(PackedTest, second) != offsetof(PackedOrig, second)) {
|
|
||||||
runtime·printf("second: size, offset = %d, %d, want %d, %d\n", sizeof(pt.second), offsetof(PackedTest, second), sizeof(po.second), offsetof(PackedOrig, second));
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
if(sizeof(pt.third) != sizeof(po.third) || offsetof(PackedTest, third) != offsetof(PackedOrig, third)) {
|
|
||||||
runtime·printf("third: size, offset = %d, %d, want %d, %d\n", sizeof(pt.third), offsetof(PackedTest, third), sizeof(po.third), offsetof(PackedOrig, third));
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
FLUSH(&ret); // flush return value
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
func test() int32 // in main.c
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
os.Exit(int(test()))
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
# Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
# Use of this source code is governed by a BSD-style
|
|
||||||
# license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
# Just add issue file prefixes to this list if more issues come up
|
|
||||||
FILE_PREFIXES="cdefstest"
|
|
||||||
|
|
||||||
for FP in $FILE_PREFIXES
|
|
||||||
do
|
|
||||||
go tool cgo -cdefs ${FP}.go > ${FP}.h
|
|
||||||
done
|
|
||||||
|
|
||||||
go build . && ./testcdefs
|
|
||||||
EXIT=$?
|
|
||||||
rm -rf _obj testcdefs *.h
|
|
||||||
exit $EXIT
|
|
||||||
|
|
@ -237,10 +237,6 @@ The following options are available when running cgo directly:
|
||||||
Write out input file in Go syntax replacing C package
|
Write out input file in Go syntax replacing C package
|
||||||
names with real values. Used to generate files in the
|
names with real values. Used to generate files in the
|
||||||
syscall package when bootstrapping a new target.
|
syscall package when bootstrapping a new target.
|
||||||
-cdefs
|
|
||||||
Like -godefs, but write file in C syntax.
|
|
||||||
Used to generate files in the runtime package when
|
|
||||||
bootstrapping a new target.
|
|
||||||
-objdir directory
|
-objdir directory
|
||||||
Put all generated files in directory.
|
Put all generated files in directory.
|
||||||
-gccgo
|
-gccgo
|
||||||
|
|
|
||||||
|
|
@ -582,7 +582,7 @@ func (p *Package) mangleName(n *Name) {
|
||||||
|
|
||||||
// rewriteRef rewrites all the C.xxx references in f.AST to refer to the
|
// rewriteRef rewrites all the C.xxx references in f.AST to refer to the
|
||||||
// Go equivalents, now that we have figured out the meaning of all
|
// Go equivalents, now that we have figured out the meaning of all
|
||||||
// the xxx. In *godefs or *cdefs mode, rewriteRef replaces the names
|
// the xxx. In *godefs mode, rewriteRef replaces the names
|
||||||
// with full definitions instead of mangled names.
|
// with full definitions instead of mangled names.
|
||||||
func (p *Package) rewriteRef(f *File) {
|
func (p *Package) rewriteRef(f *File) {
|
||||||
// Keep a list of all the functions, to remove the ones
|
// Keep a list of all the functions, to remove the ones
|
||||||
|
|
@ -688,7 +688,7 @@ func (p *Package) rewriteRef(f *File) {
|
||||||
error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
|
error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if *godefs || *cdefs {
|
if *godefs {
|
||||||
// Substitute definition for mangled type name.
|
// Substitute definition for mangled type name.
|
||||||
if id, ok := expr.(*ast.Ident); ok {
|
if id, ok := expr.(*ast.Ident); ok {
|
||||||
if t := typedef[id.Name]; t != nil {
|
if t := typedef[id.Name]; t != nil {
|
||||||
|
|
@ -992,8 +992,8 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
|
||||||
c.goVoid = c.Ident("_Ctype_void")
|
c.goVoid = c.Ident("_Ctype_void")
|
||||||
|
|
||||||
// Normally cgo translates void* to unsafe.Pointer,
|
// Normally cgo translates void* to unsafe.Pointer,
|
||||||
// but for historical reasons -cdefs and -godefs use *byte instead.
|
// but for historical reasons -godefs uses *byte instead.
|
||||||
if *cdefs || *godefs {
|
if *godefs {
|
||||||
c.goVoidPtr = &ast.StarExpr{X: c.byte}
|
c.goVoidPtr = &ast.StarExpr{X: c.byte}
|
||||||
} else {
|
} else {
|
||||||
c.goVoidPtr = c.Ident("unsafe.Pointer")
|
c.goVoidPtr = c.Ident("unsafe.Pointer")
|
||||||
|
|
@ -1334,8 +1334,8 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
|
// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
|
||||||
// use that as the Go form for this typedef too, so that the typedef will be interchangeable
|
// use that as the Go form for this typedef too, so that the typedef will be interchangeable
|
||||||
// with the base type.
|
// with the base type.
|
||||||
// In -godefs and -cdefs mode, do this for all typedefs.
|
// In -godefs mode, do this for all typedefs.
|
||||||
if isStructUnionClass(sub.Go) || *godefs || *cdefs {
|
if isStructUnionClass(sub.Go) || *godefs {
|
||||||
t.Go = sub.Go
|
t.Go = sub.Go
|
||||||
|
|
||||||
if isStructUnionClass(sub.Go) {
|
if isStructUnionClass(sub.Go) {
|
||||||
|
|
@ -1397,7 +1397,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
name := c.Ident("_Ctype_" + s)
|
name := c.Ident("_Ctype_" + s)
|
||||||
tt := *t
|
tt := *t
|
||||||
typedef[name.Name] = &tt
|
typedef[name.Name] = &tt
|
||||||
if !*godefs && !*cdefs {
|
if !*godefs {
|
||||||
t.Go = name
|
t.Go = name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1573,7 +1573,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
||||||
used[f.Name] = true
|
used[f.Name] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !*godefs && !*cdefs {
|
if !*godefs {
|
||||||
for cid, goid := range ident {
|
for cid, goid := range ident {
|
||||||
if token.Lookup(goid).IsKeyword() {
|
if token.Lookup(goid).IsKeyword() {
|
||||||
// Avoid keyword
|
// Avoid keyword
|
||||||
|
|
@ -1600,12 +1600,12 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
||||||
name := f.Name
|
name := f.Name
|
||||||
ft := f.Type
|
ft := f.Type
|
||||||
|
|
||||||
// In godefs or cdefs mode, if this field is a C11
|
// In godefs mode, if this field is a C11
|
||||||
// anonymous union then treat the first field in the
|
// anonymous union then treat the first field in the
|
||||||
// union as the field in the struct. This handles
|
// union as the field in the struct. This handles
|
||||||
// cases like the glibc <sys/resource.h> file; see
|
// cases like the glibc <sys/resource.h> file; see
|
||||||
// issue 6677.
|
// issue 6677.
|
||||||
if *godefs || *cdefs {
|
if *godefs {
|
||||||
if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
|
if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
|
||||||
name = st.Field[0].Name
|
name = st.Field[0].Name
|
||||||
ident[name] = name
|
ident[name] = name
|
||||||
|
|
@ -1635,14 +1635,12 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
||||||
talign = size
|
talign = size
|
||||||
}
|
}
|
||||||
|
|
||||||
if talign > 0 && f.ByteOffset%talign != 0 && !*cdefs {
|
if talign > 0 && f.ByteOffset%talign != 0 {
|
||||||
// Drop misaligned fields, the same way we drop integer bit fields.
|
// Drop misaligned fields, the same way we drop integer bit fields.
|
||||||
// The goal is to make available what can be made available.
|
// The goal is to make available what can be made available.
|
||||||
// Otherwise one bad and unneeded field in an otherwise okay struct
|
// Otherwise one bad and unneeded field in an otherwise okay struct
|
||||||
// makes the whole program not compile. Much of the time these
|
// makes the whole program not compile. Much of the time these
|
||||||
// structs are in system headers that cannot be corrected.
|
// structs are in system headers that cannot be corrected.
|
||||||
// Exception: In -cdefs mode, we use #pragma pack, so misaligned
|
|
||||||
// fields should still work.
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
n := len(fld)
|
n := len(fld)
|
||||||
|
|
@ -1672,7 +1670,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
||||||
buf.WriteString("}")
|
buf.WriteString("}")
|
||||||
csyntax = buf.String()
|
csyntax = buf.String()
|
||||||
|
|
||||||
if *godefs || *cdefs {
|
if *godefs {
|
||||||
godefsFields(fld)
|
godefsFields(fld)
|
||||||
}
|
}
|
||||||
expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
|
expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
|
||||||
|
|
@ -1707,9 +1705,7 @@ func godefsFields(fld []*ast.Field) {
|
||||||
n.Name = "Pad_cgo_" + strconv.Itoa(npad)
|
n.Name = "Pad_cgo_" + strconv.Itoa(npad)
|
||||||
npad++
|
npad++
|
||||||
}
|
}
|
||||||
if !*cdefs {
|
n.Name = upper(n.Name)
|
||||||
n.Name = upper(n.Name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1721,9 +1717,6 @@ func godefsFields(fld []*ast.Field) {
|
||||||
// package syscall's data structures, we drop a common prefix
|
// package syscall's data structures, we drop a common prefix
|
||||||
// (so sec, usec, which will get turned into Sec, Usec for exporting).
|
// (so sec, usec, which will get turned into Sec, Usec for exporting).
|
||||||
func fieldPrefix(fld []*ast.Field) string {
|
func fieldPrefix(fld []*ast.Field) string {
|
||||||
if *cdefs {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
prefix := ""
|
prefix := ""
|
||||||
for _, f := range fld {
|
for _, f := range fld {
|
||||||
for _, n := range f.Names {
|
for _, n := range f.Names {
|
||||||
|
|
|
||||||
|
|
@ -114,173 +114,6 @@ func (p *Package) godefs(f *File, srcfile string) string {
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// cdefs returns the output for -cdefs mode.
|
|
||||||
// The easiest way to do this is to translate the godefs Go to C.
|
|
||||||
func (p *Package) cdefs(f *File, srcfile string) string {
|
|
||||||
godefsOutput := p.godefs(f, srcfile)
|
|
||||||
|
|
||||||
lines := strings.Split(godefsOutput, "\n")
|
|
||||||
lines[0] = "// Created by cgo -cdefs - DO NOT EDIT"
|
|
||||||
|
|
||||||
for i, line := range lines {
|
|
||||||
lines[i] = strings.TrimSpace(line)
|
|
||||||
}
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
printf := func(format string, args ...interface{}) { fmt.Fprintf(&out, format, args...) }
|
|
||||||
|
|
||||||
didTypedef := false
|
|
||||||
for i := 0; i < len(lines); i++ {
|
|
||||||
line := lines[i]
|
|
||||||
|
|
||||||
// Delete
|
|
||||||
// package x
|
|
||||||
if strings.HasPrefix(line, "package ") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert
|
|
||||||
// const (
|
|
||||||
// A = 1
|
|
||||||
// B = 2
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// to
|
|
||||||
//
|
|
||||||
// enum {
|
|
||||||
// A = 1,
|
|
||||||
// B = 2,
|
|
||||||
// };
|
|
||||||
if line == "const (" {
|
|
||||||
printf("enum {\n")
|
|
||||||
for i++; i < len(lines) && lines[i] != ")"; i++ {
|
|
||||||
line = lines[i]
|
|
||||||
if line != "" {
|
|
||||||
printf("\t%s,", line)
|
|
||||||
}
|
|
||||||
printf("\n")
|
|
||||||
}
|
|
||||||
printf("};\n")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert
|
|
||||||
// const A = 1
|
|
||||||
// to
|
|
||||||
// enum { A = 1 };
|
|
||||||
if strings.HasPrefix(line, "const ") {
|
|
||||||
printf("enum { %s };\n", line[len("const "):])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// On first type definition, typedef all the structs
|
|
||||||
// in case there are dependencies between them.
|
|
||||||
if !didTypedef && strings.HasPrefix(line, "type ") {
|
|
||||||
didTypedef = true
|
|
||||||
for _, line := range lines {
|
|
||||||
line = strings.TrimSpace(line)
|
|
||||||
if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") {
|
|
||||||
s := strings.TrimSuffix(strings.TrimPrefix(line, "type "), " struct {")
|
|
||||||
printf("typedef struct %s %s;\n", s, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n")
|
|
||||||
printf("#pragma pack on\n")
|
|
||||||
printf("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert
|
|
||||||
// type T struct {
|
|
||||||
// X int64
|
|
||||||
// Y *int32
|
|
||||||
// Z [4]byte
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// to
|
|
||||||
//
|
|
||||||
// struct T {
|
|
||||||
// int64 X;
|
|
||||||
// int32 *Y;
|
|
||||||
// byte Z[4];
|
|
||||||
// }
|
|
||||||
if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") {
|
|
||||||
if len(lines) > i+1 && lines[i+1] == "}" {
|
|
||||||
// do not output empty struct
|
|
||||||
i++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s := line[len("type ") : len(line)-len(" struct {")]
|
|
||||||
printf("struct %s {\n", s)
|
|
||||||
for i++; i < len(lines) && lines[i] != "}"; i++ {
|
|
||||||
line := lines[i]
|
|
||||||
if line != "" {
|
|
||||||
f := strings.Fields(line)
|
|
||||||
if len(f) != 2 {
|
|
||||||
fmt.Fprintf(os.Stderr, "cgo: cannot parse struct field: %s\n", line)
|
|
||||||
nerrors++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
printf("\t%s;", cdecl(f[0], f[1]))
|
|
||||||
}
|
|
||||||
printf("\n")
|
|
||||||
}
|
|
||||||
printf("};\n")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert
|
|
||||||
// type T int
|
|
||||||
// to
|
|
||||||
// typedef int T;
|
|
||||||
if strings.HasPrefix(line, "type ") {
|
|
||||||
f := strings.Fields(line[len("type "):])
|
|
||||||
if len(f) != 2 {
|
|
||||||
fmt.Fprintf(os.Stderr, "cgo: cannot parse type definition: %s\n", line)
|
|
||||||
nerrors++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
printf("typedef\t%s;\n", cdecl(f[0], f[1]))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", line)
|
|
||||||
}
|
|
||||||
|
|
||||||
if didTypedef {
|
|
||||||
printf("\n")
|
|
||||||
printf("#pragma pack off\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
return out.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// cdecl returns the C declaration for the given Go name and type.
|
|
||||||
// It only handles the specific cases necessary for converting godefs output.
|
|
||||||
func cdecl(name, typ string) string {
|
|
||||||
// X *[0]byte -> X *void
|
|
||||||
if strings.HasPrefix(typ, "*[0]") {
|
|
||||||
typ = "*void"
|
|
||||||
}
|
|
||||||
// X [4]byte -> X[4] byte
|
|
||||||
for strings.HasPrefix(typ, "[") {
|
|
||||||
i := strings.Index(typ, "]") + 1
|
|
||||||
name = name + typ[:i]
|
|
||||||
typ = typ[i:]
|
|
||||||
}
|
|
||||||
// X *byte -> *X byte
|
|
||||||
for strings.HasPrefix(typ, "*") {
|
|
||||||
name = "*" + name
|
|
||||||
typ = typ[1:]
|
|
||||||
}
|
|
||||||
// X T -> T X
|
|
||||||
// Handle the special case: 'unsafe.Pointer' is 'void *'
|
|
||||||
if typ == "unsafe.Pointer" {
|
|
||||||
typ = "void"
|
|
||||||
name = "*" + name
|
|
||||||
}
|
|
||||||
return typ + "\t" + name
|
|
||||||
}
|
|
||||||
|
|
||||||
var gofmtBuf bytes.Buffer
|
var gofmtBuf bytes.Buffer
|
||||||
|
|
||||||
// gofmt returns the gofmt-formatted string for an AST node.
|
// gofmt returns the gofmt-formatted string for an AST node.
|
||||||
|
|
|
||||||
|
|
@ -155,10 +155,9 @@ var dynpackage = flag.String("dynpackage", "main", "set Go package for -dynimpor
|
||||||
var dynlinker = flag.Bool("dynlinker", false, "record dynamic linker information in -dynimport mode")
|
var dynlinker = flag.Bool("dynlinker", false, "record dynamic linker information in -dynimport mode")
|
||||||
|
|
||||||
// These flags are for bootstrapping a new Go implementation,
|
// These flags are for bootstrapping a new Go implementation,
|
||||||
// to generate Go and C headers that match the data layout and
|
// to generate Go types that match the data layout and
|
||||||
// constant values used in the host's C libraries and system calls.
|
// constant values used in the host's C libraries and system calls.
|
||||||
var godefs = flag.Bool("godefs", false, "for bootstrap: write Go definitions for C file to standard output")
|
var godefs = flag.Bool("godefs", false, "for bootstrap: write Go definitions for C file to standard output")
|
||||||
var cdefs = flag.Bool("cdefs", false, "for bootstrap: write C definitions for C file to standard output")
|
|
||||||
var objDir = flag.String("objdir", "", "object directory")
|
var objDir = flag.String("objdir", "", "object directory")
|
||||||
|
|
||||||
var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo")
|
var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo")
|
||||||
|
|
@ -185,12 +184,7 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if *godefs && *cdefs {
|
if *godefs {
|
||||||
fmt.Fprintf(os.Stderr, "cgo: cannot use -cdefs and -godefs together\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
if *godefs || *cdefs {
|
|
||||||
// Generating definitions pulled from header files,
|
// Generating definitions pulled from header files,
|
||||||
// to be checked into Go repositories.
|
// to be checked into Go repositories.
|
||||||
// Line numbers are just noise.
|
// Line numbers are just noise.
|
||||||
|
|
@ -282,14 +276,12 @@ func main() {
|
||||||
p.Record(f)
|
p.Record(f)
|
||||||
if *godefs {
|
if *godefs {
|
||||||
os.Stdout.WriteString(p.godefs(f, input))
|
os.Stdout.WriteString(p.godefs(f, input))
|
||||||
} else if *cdefs {
|
|
||||||
os.Stdout.WriteString(p.cdefs(f, input))
|
|
||||||
} else {
|
} else {
|
||||||
p.writeOutput(f, input)
|
p.writeOutput(f, input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !*godefs && !*cdefs {
|
if !*godefs {
|
||||||
p.writeDefs()
|
p.writeDefs()
|
||||||
}
|
}
|
||||||
if nerrors > 0 {
|
if nerrors > 0 {
|
||||||
|
|
|
||||||
11
src/run.bash
11
src/run.bash
|
|
@ -181,17 +181,6 @@ linux-linux-amd64-1 | freebsd-freebsd-amd64-1 | darwin-darwin-amd64-1)
|
||||||
fi
|
fi
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# This tests cgo -cdefs. That mode is not supported,
|
|
||||||
# so it's okay if it doesn't work on some systems.
|
|
||||||
# In particular, it works badly with clang on OS X.
|
|
||||||
# It doesn't work at all now that we disallow C code
|
|
||||||
# outside runtime. Once runtime has no C code it won't
|
|
||||||
# even be necessary.
|
|
||||||
# [ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] ||
|
|
||||||
# (xcd ../misc/cgo/testcdefs
|
|
||||||
# ./test.bash || exit 1
|
|
||||||
# ) || exit $?
|
|
||||||
|
|
||||||
[ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] ||
|
[ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] ||
|
||||||
(xcd ../misc/cgo/testgodefs
|
(xcd ../misc/cgo/testgodefs
|
||||||
./test.bash || exit 1
|
./test.bash || exit 1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue