cgo: create new GenDecl for every symbol
Previously, a GenDecl was shared between many different consts/vars/types. However, it actually makes much more sense not to bundle them as that is also the case in C. This makes the printed output of the CGo AST much nicer, and works around a bug in Go 1.11.
Этот коммит содержится в:
родитель
2a5ab2500d
коммит
b72f677310
1 изменённых файлов: 52 добавлений и 58 удалений
110
cgo/cgo.go
110
cgo/cgo.go
|
@ -346,18 +346,18 @@ func (p *cgoPackage) addFuncPtrDecls() {
|
||||||
if len(p.functions) == 0 {
|
if len(p.functions) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gen := &ast.GenDecl{
|
|
||||||
TokPos: token.NoPos,
|
|
||||||
Tok: token.VAR,
|
|
||||||
Lparen: token.NoPos,
|
|
||||||
Rparen: token.NoPos,
|
|
||||||
}
|
|
||||||
names := make([]string, 0, len(p.functions))
|
names := make([]string, 0, len(p.functions))
|
||||||
for name := range p.functions {
|
for name := range p.functions {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
|
gen := &ast.GenDecl{
|
||||||
|
TokPos: token.NoPos,
|
||||||
|
Tok: token.VAR,
|
||||||
|
Lparen: token.NoPos,
|
||||||
|
Rparen: token.NoPos,
|
||||||
|
}
|
||||||
fn := p.functions[name]
|
fn := p.functions[name]
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Typ,
|
Kind: ast.Typ,
|
||||||
|
@ -382,34 +382,32 @@ func (p *cgoPackage) addFuncPtrDecls() {
|
||||||
}
|
}
|
||||||
obj.Decl = valueSpec
|
obj.Decl = valueSpec
|
||||||
gen.Specs = append(gen.Specs, valueSpec)
|
gen.Specs = append(gen.Specs, valueSpec)
|
||||||
|
p.generated.Decls = append(p.generated.Decls, gen)
|
||||||
}
|
}
|
||||||
p.generated.Decls = append(p.generated.Decls, gen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addConstDecls declares external C constants in the Go source.
|
// addConstDecls declares external C constants in the Go source.
|
||||||
// It adds code like the following to the AST:
|
// It adds code like the following to the AST:
|
||||||
//
|
//
|
||||||
// const (
|
// const C.CONST_INT = 5
|
||||||
// C.CONST_INT = 5
|
// const C.CONST_FLOAT = 5.8
|
||||||
// C.CONST_FLOAT = 5.8
|
// // ...
|
||||||
// // ...
|
|
||||||
// )
|
|
||||||
func (p *cgoPackage) addConstDecls() {
|
func (p *cgoPackage) addConstDecls() {
|
||||||
if len(p.constants) == 0 {
|
if len(p.constants) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gen := &ast.GenDecl{
|
|
||||||
TokPos: token.NoPos,
|
|
||||||
Tok: token.CONST,
|
|
||||||
Lparen: token.NoPos,
|
|
||||||
Rparen: token.NoPos,
|
|
||||||
}
|
|
||||||
names := make([]string, 0, len(p.constants))
|
names := make([]string, 0, len(p.constants))
|
||||||
for name := range p.constants {
|
for name := range p.constants {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
|
gen := &ast.GenDecl{
|
||||||
|
TokPos: token.NoPos,
|
||||||
|
Tok: token.CONST,
|
||||||
|
Lparen: token.NoPos,
|
||||||
|
Rparen: token.NoPos,
|
||||||
|
}
|
||||||
constVal := p.constants[name]
|
constVal := p.constants[name]
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Con,
|
Kind: ast.Con,
|
||||||
|
@ -425,34 +423,32 @@ func (p *cgoPackage) addConstDecls() {
|
||||||
}
|
}
|
||||||
obj.Decl = valueSpec
|
obj.Decl = valueSpec
|
||||||
gen.Specs = append(gen.Specs, valueSpec)
|
gen.Specs = append(gen.Specs, valueSpec)
|
||||||
|
p.generated.Decls = append(p.generated.Decls, gen)
|
||||||
}
|
}
|
||||||
p.generated.Decls = append(p.generated.Decls, gen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addVarDecls declares external C globals in the Go source.
|
// addVarDecls declares external C globals in the Go source.
|
||||||
// It adds code like the following to the AST:
|
// It adds code like the following to the AST:
|
||||||
//
|
//
|
||||||
// var (
|
// var C.globalInt int
|
||||||
// C.globalInt int
|
// var C.globalBool bool
|
||||||
// C.globalBool bool
|
// // ...
|
||||||
// // ...
|
|
||||||
// )
|
|
||||||
func (p *cgoPackage) addVarDecls() {
|
func (p *cgoPackage) addVarDecls() {
|
||||||
if len(p.globals) == 0 {
|
if len(p.globals) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gen := &ast.GenDecl{
|
|
||||||
TokPos: token.NoPos,
|
|
||||||
Tok: token.VAR,
|
|
||||||
Lparen: token.NoPos,
|
|
||||||
Rparen: token.NoPos,
|
|
||||||
}
|
|
||||||
names := make([]string, 0, len(p.globals))
|
names := make([]string, 0, len(p.globals))
|
||||||
for name := range p.globals {
|
for name := range p.globals {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
|
gen := &ast.GenDecl{
|
||||||
|
TokPos: token.NoPos,
|
||||||
|
Tok: token.VAR,
|
||||||
|
Lparen: token.NoPos,
|
||||||
|
Rparen: token.NoPos,
|
||||||
|
}
|
||||||
global := p.globals[name]
|
global := p.globals[name]
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Var,
|
Kind: ast.Var,
|
||||||
|
@ -468,31 +464,29 @@ func (p *cgoPackage) addVarDecls() {
|
||||||
}
|
}
|
||||||
obj.Decl = valueSpec
|
obj.Decl = valueSpec
|
||||||
gen.Specs = append(gen.Specs, valueSpec)
|
gen.Specs = append(gen.Specs, valueSpec)
|
||||||
|
p.generated.Decls = append(p.generated.Decls, gen)
|
||||||
}
|
}
|
||||||
p.generated.Decls = append(p.generated.Decls, gen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addTypeAliases aliases some built-in Go types with their equivalent C types.
|
// addTypeAliases aliases some built-in Go types with their equivalent C types.
|
||||||
// It adds code like the following to the AST:
|
// It adds code like the following to the AST:
|
||||||
//
|
//
|
||||||
// type (
|
// type C.int8_t = int8
|
||||||
// C.int8_t = int8
|
// type C.int16_t = int16
|
||||||
// C.int16_t = int16
|
// // ...
|
||||||
// // ...
|
|
||||||
// )
|
|
||||||
func (p *cgoPackage) addTypeAliases() {
|
func (p *cgoPackage) addTypeAliases() {
|
||||||
aliasKeys := make([]string, 0, len(cgoAliases))
|
aliasKeys := make([]string, 0, len(cgoAliases))
|
||||||
for key := range cgoAliases {
|
for key := range cgoAliases {
|
||||||
aliasKeys = append(aliasKeys, key)
|
aliasKeys = append(aliasKeys, key)
|
||||||
}
|
}
|
||||||
sort.Strings(aliasKeys)
|
sort.Strings(aliasKeys)
|
||||||
gen := &ast.GenDecl{
|
|
||||||
TokPos: token.NoPos,
|
|
||||||
Tok: token.TYPE,
|
|
||||||
Lparen: token.NoPos,
|
|
||||||
Rparen: token.NoPos,
|
|
||||||
}
|
|
||||||
for _, typeName := range aliasKeys {
|
for _, typeName := range aliasKeys {
|
||||||
|
gen := &ast.GenDecl{
|
||||||
|
TokPos: token.NoPos,
|
||||||
|
Tok: token.TYPE,
|
||||||
|
Lparen: token.NoPos,
|
||||||
|
Rparen: token.NoPos,
|
||||||
|
}
|
||||||
goTypeName := cgoAliases[typeName]
|
goTypeName := cgoAliases[typeName]
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Typ,
|
Kind: ast.Typ,
|
||||||
|
@ -512,24 +506,24 @@ func (p *cgoPackage) addTypeAliases() {
|
||||||
}
|
}
|
||||||
obj.Decl = typeSpec
|
obj.Decl = typeSpec
|
||||||
gen.Specs = append(gen.Specs, typeSpec)
|
gen.Specs = append(gen.Specs, typeSpec)
|
||||||
|
p.generated.Decls = append(p.generated.Decls, gen)
|
||||||
}
|
}
|
||||||
p.generated.Decls = append(p.generated.Decls, gen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *cgoPackage) addTypedefs() {
|
func (p *cgoPackage) addTypedefs() {
|
||||||
if len(p.typedefs) == 0 {
|
if len(p.typedefs) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gen := &ast.GenDecl{
|
|
||||||
TokPos: token.NoPos,
|
|
||||||
Tok: token.TYPE,
|
|
||||||
}
|
|
||||||
names := make([]string, 0, len(p.typedefs))
|
names := make([]string, 0, len(p.typedefs))
|
||||||
for name := range p.typedefs {
|
for name := range p.typedefs {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
|
gen := &ast.GenDecl{
|
||||||
|
TokPos: token.NoPos,
|
||||||
|
Tok: token.TYPE,
|
||||||
|
}
|
||||||
typedef := p.typedefs[name]
|
typedef := p.typedefs[name]
|
||||||
typeName := "C." + name
|
typeName := "C." + name
|
||||||
isAlias := true
|
isAlias := true
|
||||||
|
@ -558,8 +552,8 @@ func (p *cgoPackage) addTypedefs() {
|
||||||
}
|
}
|
||||||
obj.Decl = typeSpec
|
obj.Decl = typeSpec
|
||||||
gen.Specs = append(gen.Specs, typeSpec)
|
gen.Specs = append(gen.Specs, typeSpec)
|
||||||
|
p.generated.Decls = append(p.generated.Decls, gen)
|
||||||
}
|
}
|
||||||
p.generated.Decls = append(p.generated.Decls, gen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addElaboratedTypes adds C elaborated types as aliases. These are the "struct
|
// addElaboratedTypes adds C elaborated types as aliases. These are the "struct
|
||||||
|
@ -571,16 +565,16 @@ func (p *cgoPackage) addElaboratedTypes() {
|
||||||
if len(p.elaboratedTypes) == 0 {
|
if len(p.elaboratedTypes) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gen := &ast.GenDecl{
|
|
||||||
TokPos: token.NoPos,
|
|
||||||
Tok: token.TYPE,
|
|
||||||
}
|
|
||||||
names := make([]string, 0, len(p.elaboratedTypes))
|
names := make([]string, 0, len(p.elaboratedTypes))
|
||||||
for name := range p.elaboratedTypes {
|
for name := range p.elaboratedTypes {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
|
gen := &ast.GenDecl{
|
||||||
|
TokPos: token.NoPos,
|
||||||
|
Tok: token.TYPE,
|
||||||
|
}
|
||||||
typ := p.elaboratedTypes[name]
|
typ := p.elaboratedTypes[name]
|
||||||
typeName := "C." + name
|
typeName := "C." + name
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
|
@ -602,8 +596,8 @@ func (p *cgoPackage) addElaboratedTypes() {
|
||||||
p.createBitfieldGetter(bitfield, typeName)
|
p.createBitfieldGetter(bitfield, typeName)
|
||||||
p.createBitfieldSetter(bitfield, typeName)
|
p.createBitfieldSetter(bitfield, typeName)
|
||||||
}
|
}
|
||||||
|
p.generated.Decls = append(p.generated.Decls, gen)
|
||||||
}
|
}
|
||||||
p.generated.Decls = append(p.generated.Decls, gen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// createBitfieldGetter creates a bitfield getter function like the following:
|
// createBitfieldGetter creates a bitfield getter function like the following:
|
||||||
|
@ -908,16 +902,16 @@ func (p *cgoPackage) addEnumTypes() {
|
||||||
if len(p.enums) == 0 {
|
if len(p.enums) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gen := &ast.GenDecl{
|
|
||||||
TokPos: token.NoPos,
|
|
||||||
Tok: token.TYPE,
|
|
||||||
}
|
|
||||||
names := make([]string, 0, len(p.enums))
|
names := make([]string, 0, len(p.enums))
|
||||||
for name := range p.enums {
|
for name := range p.enums {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
|
gen := &ast.GenDecl{
|
||||||
|
TokPos: token.NoPos,
|
||||||
|
Tok: token.TYPE,
|
||||||
|
}
|
||||||
typ := p.enums[name]
|
typ := p.enums[name]
|
||||||
typeName := "C.enum_" + name
|
typeName := "C.enum_" + name
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
|
@ -934,8 +928,8 @@ func (p *cgoPackage) addEnumTypes() {
|
||||||
}
|
}
|
||||||
obj.Decl = typeSpec
|
obj.Decl = typeSpec
|
||||||
gen.Specs = append(gen.Specs, typeSpec)
|
gen.Specs = append(gen.Specs, typeSpec)
|
||||||
|
p.generated.Decls = append(p.generated.Decls, gen)
|
||||||
}
|
}
|
||||||
p.generated.Decls = append(p.generated.Decls, gen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// findMissingCGoNames traverses the AST and finds all C.something names. Only
|
// findMissingCGoNames traverses the AST and finds all C.something names. Only
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче