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 удалений
94
cgo/cgo.go
94
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)
|
||||||
|
for _, typeName := range aliasKeys {
|
||||||
gen := &ast.GenDecl{
|
gen := &ast.GenDecl{
|
||||||
TokPos: token.NoPos,
|
TokPos: token.NoPos,
|
||||||
Tok: token.TYPE,
|
Tok: token.TYPE,
|
||||||
Lparen: token.NoPos,
|
Lparen: token.NoPos,
|
||||||
Rparen: token.NoPos,
|
Rparen: token.NoPos,
|
||||||
}
|
}
|
||||||
for _, typeName := range aliasKeys {
|
|
||||||
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,9 +552,9 @@ 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
|
||||||
// foo" or "union foo" types, often used in a typedef.
|
// foo" or "union foo" types, often used in a typedef.
|
||||||
|
@ -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,9 +596,9 @@ 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,9 +928,9 @@ 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
|
||||||
// these symbols are extracted from the parsed C AST and converted to the Go
|
// these symbols are extracted from the parsed C AST and converted to the Go
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче