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.
Этот коммит содержится в:
Ayke van Laethem 2019-11-03 18:30:32 +01:00 коммит произвёл Ron Evans
родитель 2a5ab2500d
коммит b72f677310

Просмотреть файл

@ -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