From 1a4998a6423ef385508b8c848e4939698f482961 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 11 Oct 2024 14:53:44 +0800 Subject: [PATCH 1/6] gogensig:size_t --- chore/gogensig/convert/builtin.go | 3 +++ chore/gogensig/convert/package.go | 1 + 2 files changed, 4 insertions(+) diff --git a/chore/gogensig/convert/builtin.go b/chore/gogensig/convert/builtin.go index 5796937ce..d1f29d7c0 100644 --- a/chore/gogensig/convert/builtin.go +++ b/chore/gogensig/convert/builtin.go @@ -109,5 +109,8 @@ func (p *BuiltinTypeMap) initBuiltinTypeMap() { "int64_t": {Type: p.CType("LongLong"), HeaderFile: "sys/_types/_int64_t.h"}, "uint64_t": {Type: p.CType("UlongLong"), HeaderFile: "_types/_uint64_t.h"}, "u_int64_t": {Type: p.CType("UlongLong"), HeaderFile: "sys/_types/_u_int64_t.h"}, + // todo(zzy): undef type log + // other headerfile + "size_t": {Type: types.Typ[types.Uintptr], HeaderFile: "sys/_types/_u_int64_t.h"}, } } diff --git a/chore/gogensig/convert/package.go b/chore/gogensig/convert/package.go index adbb6c223..421a8fd93 100644 --- a/chore/gogensig/convert/package.go +++ b/chore/gogensig/convert/package.go @@ -139,6 +139,7 @@ func (p *Package) NewFuncDecl(funcDecl *ast.FuncDecl) error { } sig, err := p.cvt.ToSignature(funcDecl.Type) if err != nil { + log.Printf("FuncDeclToSignature Fail: %s\n", err.Error()) return err } decl := p.p.NewFuncDecl(token.NoPos, string(goFuncName), sig) From 1c698637042c2fb62cfcdde627be137bd9a1e584 Mon Sep 17 00:00:00 2001 From: tsingbx Date: Sun, 13 Oct 2024 00:04:54 +0800 Subject: [PATCH 2/6] convert includes of ast file before convert ast file, fix type redefine panic, size_t type can not find panic --- chore/gogensig/convert/builtin.go | 2 +- chore/gogensig/convert/convert_test.go | 39 ++++++++++++++-- chore/gogensig/convert/package.go | 14 +++++- chore/gogensig/processor/processor.go | 62 ++++++++++++++++++++++++-- chore/gogensig/unmarshal/unmarshal.go | 35 ++++++++++++++- 5 files changed, 140 insertions(+), 12 deletions(-) diff --git a/chore/gogensig/convert/builtin.go b/chore/gogensig/convert/builtin.go index d1f29d7c0..79df14e14 100644 --- a/chore/gogensig/convert/builtin.go +++ b/chore/gogensig/convert/builtin.go @@ -111,6 +111,6 @@ func (p *BuiltinTypeMap) initBuiltinTypeMap() { "u_int64_t": {Type: p.CType("UlongLong"), HeaderFile: "sys/_types/_u_int64_t.h"}, // todo(zzy): undef type log // other headerfile - "size_t": {Type: types.Typ[types.Uintptr], HeaderFile: "sys/_types/_u_int64_t.h"}, + //"size_t": {Type: types.Typ[types.Uintptr], HeaderFile: "sys/_types/_u_int64_t.h"}, } } diff --git a/chore/gogensig/convert/convert_test.go b/chore/gogensig/convert/convert_test.go index cd5ffe7f1..169f1970f 100644 --- a/chore/gogensig/convert/convert_test.go +++ b/chore/gogensig/convert/convert_test.go @@ -9,6 +9,39 @@ import ( cppgtypes "github.com/goplus/llgo/chore/llcppg/types" ) +func TestSizeT(t *testing.T) { + cmptest.RunTest(t, "size_t", false, []config.SymbolEntry{ + {MangleName: "testSize", CppName: "testSize", GoName: "TestSize"}, + }, &cppgtypes.Config{}, ` +#include + +void testSize(size_t a); + `, ` +// Code generated by gogen; DO NOT EDIT. + +package size_t + +import _ "unsafe" +//go:linkname TestSize C.testSize +func TestSize(a size_t) + `, func(t *testing.T, pkg *convert.Package) { + files, err := os.ReadDir(pkg.GetOutputDir()) + if err != nil { + t.Fatal(err) + } + + for _, file := range files { + log.Println("Generated file:", file.Name()) + typeAliasMap := convert.NewBuiltinTypeMap(".", "temp", nil).GetTypeAliases() + for _, v := range typeAliasMap { + if file.Name() == convert.HeaderFileToGo(v.HeaderFile) { + t.Fatal("skip file should not be output") + } + } + } + }) +} + func TestCommentSlashSlashSlash(t *testing.T) { cmptest.RunTest(t, "comment", false, []config.SymbolEntry{ { @@ -242,13 +275,13 @@ void testUint(u_int8_t a, u_int16_t b, u_int32_t c, u_int64_t d); package skip import ( - "github.com/goplus/llgo/c" + c7 "github.com/goplus/llgo/c" _ "unsafe" ) //go:linkname TestInt C.testInt -func TestInt(a int8, b int16, c c.Int, d c.LongLong) +func TestInt(a int8, b int16, c c7.Int, d c7.LongLong) //go:linkname TestUint C.testUint -func TestUint(a int8, b uint16, c c.Uint, d c.UlongLong) +func TestUint(a int8, b uint16, c c7.Uint, d c7.UlongLong) `, func(t *testing.T, pkg *convert.Package) { files, err := os.ReadDir(pkg.GetOutputDir()) if err != nil { diff --git a/chore/gogensig/convert/package.go b/chore/gogensig/convert/package.go index 421a8fd93..964b85cd1 100644 --- a/chore/gogensig/convert/package.go +++ b/chore/gogensig/convert/package.go @@ -37,6 +37,7 @@ type Package struct { p *gogen.Package cvt *TypeConv outputDir string + newTypes map[string]struct{} } type PackageConfig struct { @@ -67,6 +68,7 @@ func NewPackage(config *PackageConfig) *Package { clib := p.p.Import("github.com/goplus/llgo/c") typeMap := NewBuiltinTypeMapWithPkgRefS(clib, p.p.Unsafe()) p.cvt = NewConv(p.p.Types, typeMap) + p.newTypes = make(map[string]struct{}, 0) return p } @@ -151,10 +153,13 @@ func (p *Package) NewFuncDecl(funcDecl *ast.FuncDecl) error { // todo(zzy): for class,union,struct func (p *Package) NewTypeDecl(typeDecl *ast.TypeDecl) error { + name := p.cvt.RemovePrefixedName(typeDecl.Name.Name) + if _, ok := p.newTypes[name]; ok { + return nil + } if debug { log.Printf("NewTypeDecl: %s\n", typeDecl.Name.Name) } - name := p.cvt.RemovePrefixedName(typeDecl.Name.Name) typeBlock := p.p.NewTypeDefs() typeBlock.SetComments(CommentGroup(typeDecl.Doc).CommentGroup) decl := typeBlock.NewType(name) @@ -163,10 +168,15 @@ func (p *Package) NewTypeDecl(typeDecl *ast.TypeDecl) error { return err } decl.InitType(p.p, structType) + p.newTypes[name] = struct{}{} return nil } func (p *Package) NewTypedefDecl(typedefDecl *ast.TypedefDecl) error { + name := p.cvt.RemovePrefixedName(typedefDecl.Name.Name) + if _, ok := p.newTypes[name]; ok { + return nil + } if debug { log.Printf("NewTypedefDecl: %s\n", typedefDecl.Name.Name) } @@ -179,7 +189,6 @@ func (p *Package) NewTypedefDecl(typedefDecl *ast.TypedefDecl) error { if typ == nil { return fmt.Errorf("underlying type must not be nil") } - name := p.cvt.RemovePrefixedName(typedefDecl.Name.Name) if named, ok := typ.(*types.Named); ok { // Compare the type name with typedefDecl.Name.Name if named.Obj().Name() == name { @@ -189,6 +198,7 @@ func (p *Package) NewTypedefDecl(typedefDecl *ast.TypedefDecl) error { } typeSpecdecl := genDecl.NewType(name) typeSpecdecl.InitType(p.p, typ) + p.newTypes[name] = struct{}{} if _, ok := typ.(*types.Signature); ok { genDecl.SetComments(NewTypecDocComments()) } diff --git a/chore/gogensig/processor/processor.go b/chore/gogensig/processor/processor.go index 63c686050..9c7a28927 100644 --- a/chore/gogensig/processor/processor.go +++ b/chore/gogensig/processor/processor.go @@ -1,6 +1,9 @@ package processor import ( + "os" + "path/filepath" + "github.com/goplus/llgo/chore/gogensig/config" "github.com/goplus/llgo/chore/gogensig/unmarshal" "github.com/goplus/llgo/chore/gogensig/visitor" @@ -25,17 +28,68 @@ func (p *DocVisitorManager) visit(node ast.Node, docPath string) bool { } type DocFileSetProcessor struct { - docVisitorList []visitor.DocVisitor + docVisitorList []visitor.DocVisitor + absPathFunc func(s string, files unmarshal.FileSet) string + visitedFile map[string]struct{} + visitedIncludeFile map[string]struct{} } func NewDocFileSetProcessor(docVisitorList []visitor.DocVisitor) *DocFileSetProcessor { - return &DocFileSetProcessor{docVisitorList: docVisitorList} + p := &DocFileSetProcessor{docVisitorList: docVisitorList} + p.visitedFile = make(map[string]struct{}) + p.visitedIncludeFile = make(map[string]struct{}) + includes := make([]string, 0) + initIncludes := false + p.SetAbsPathFunc(func(s string, fs unmarshal.FileSet) string { + if !initIncludes { + includes = append(includes, fs.IncludeDir()) + initIncludes = true + } + if filepath.IsAbs(s) { + return s + } + for _, includePath := range includes { + absIncludePath := filepath.Join(includePath, s) + _, err := os.Stat(absIncludePath) + if err == nil { + return absIncludePath + } + } + return s + }) + return p +} + +func (p *DocFileSetProcessor) SetAbsPathFunc(fn func(s string, files unmarshal.FileSet) string) { + p.absPathFunc = fn +} + +func (p *DocFileSetProcessor) visitFile(docVisitor *DocVisitorManager, file unmarshal.FileEntry, files unmarshal.FileSet) { + if _, ok := p.visitedFile[file.Path]; ok { + return + } + if p.absPathFunc != nil { + for _, inc := range file.Doc.Includes { + if _, ok := p.visitedIncludeFile[inc.Path]; ok { + continue + } + p.visitedIncludeFile[inc.Path] = struct{}{} + absPath := p.absPathFunc(inc.Path, files) + idx := files.FindEntry(absPath) + if idx >= 0 { + findFile := files[idx] + p.visitFile(docVisitor, findFile, files) + } + } + } + docVisitor.visit(file.Doc, file.Path) + p.visitedFile[file.Path] = struct{}{} } func (p *DocFileSetProcessor) ProcessFileSet(files unmarshal.FileSet) error { + docVisitor := NewDocVisitorManager(p.docVisitorList) for _, file := range files { - docVisitor := NewDocVisitorManager(p.docVisitorList) - docVisitor.visit(file.Doc, file.Path) + p.visitFile(docVisitor, file, files) } return nil } diff --git a/chore/gogensig/unmarshal/unmarshal.go b/chore/gogensig/unmarshal/unmarshal.go index 9cb1cdb1c..95d3b9e1b 100644 --- a/chore/gogensig/unmarshal/unmarshal.go +++ b/chore/gogensig/unmarshal/unmarshal.go @@ -3,6 +3,7 @@ package unmarshal import ( "encoding/json" "fmt" + "strings" "github.com/goplus/llgo/chore/llcppg/ast" ) @@ -13,9 +14,39 @@ var nodeUnmarshalers map[string]NodeUnmarshaler type FileSet []FileEntry +func (s FileSet) FindEntry(absIncludePath string) int { + for i, e := range s { + if e.Path == absIncludePath { + return i + } + } + return -1 +} + +func (s FileSet) IncludeDir() string { + paths := make([]string, 0) + includes := make([]string, 0) + for _, f := range s { + paths = append(paths, f.Path) + for _, inc := range f.Doc.Includes { + includes = append(includes, inc.Path) + } + } + for _, path := range paths { + for _, inc := range includes { + after, found := strings.CutSuffix(path, inc) + if found { + return after + } + } + } + return "" +} + type FileEntry struct { - Path string - Doc *ast.File + Path string + Doc *ast.File + Visited bool } func init() { From 910124fdc605151e21964657a3c9dd3dc9f418ab Mon Sep 17 00:00:00 2001 From: tsingbx Date: Sun, 13 Oct 2024 00:10:12 +0800 Subject: [PATCH 3/6] remove visited field of FileEntry --- chore/gogensig/unmarshal/unmarshal.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/chore/gogensig/unmarshal/unmarshal.go b/chore/gogensig/unmarshal/unmarshal.go index 95d3b9e1b..5d063b120 100644 --- a/chore/gogensig/unmarshal/unmarshal.go +++ b/chore/gogensig/unmarshal/unmarshal.go @@ -44,9 +44,8 @@ func (s FileSet) IncludeDir() string { } type FileEntry struct { - Path string - Doc *ast.File - Visited bool + Path string + Doc *ast.File } func init() { From 1217b6df90e1e044cdf329aac714d64b8ce83ea7 Mon Sep 17 00:00:00 2001 From: tsingbx Date: Mon, 14 Oct 2024 10:54:04 +0800 Subject: [PATCH 4/6] change IncludeDir --- chore/gogensig/convert/convert_test.go | 8 +++++--- chore/gogensig/convert/package.go | 2 +- chore/gogensig/unmarshal/unmarshal.go | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/chore/gogensig/convert/convert_test.go b/chore/gogensig/convert/convert_test.go index 169f1970f..e5ccc8bbd 100644 --- a/chore/gogensig/convert/convert_test.go +++ b/chore/gogensig/convert/convert_test.go @@ -1,6 +1,8 @@ package convert_test import ( + "log" + "os" "testing" "github.com/goplus/llgo/chore/gogensig/cmptest" @@ -275,13 +277,13 @@ void testUint(u_int8_t a, u_int16_t b, u_int32_t c, u_int64_t d); package skip import ( - c7 "github.com/goplus/llgo/c" + c "github.com/goplus/llgo/c" _ "unsafe" ) //go:linkname TestInt C.testInt -func TestInt(a int8, b int16, c c7.Int, d c7.LongLong) +func TestInt(a int8, b int16, c c.Int, d c.LongLong) //go:linkname TestUint C.testUint -func TestUint(a int8, b uint16, c c7.Uint, d c7.UlongLong) +func TestUint(a int8, b uint16, c c.Uint, d c.UlongLong) `, func(t *testing.T, pkg *convert.Package) { files, err := os.ReadDir(pkg.GetOutputDir()) if err != nil { diff --git a/chore/gogensig/convert/package.go b/chore/gogensig/convert/package.go index 964b85cd1..bd3523179 100644 --- a/chore/gogensig/convert/package.go +++ b/chore/gogensig/convert/package.go @@ -37,7 +37,7 @@ type Package struct { p *gogen.Package cvt *TypeConv outputDir string - newTypes map[string]struct{} + newTypes map[string]struct{} //todo(xlj): Temporary solution to avoid crashes } type PackageConfig struct { diff --git a/chore/gogensig/unmarshal/unmarshal.go b/chore/gogensig/unmarshal/unmarshal.go index 5d063b120..7b8c19ee4 100644 --- a/chore/gogensig/unmarshal/unmarshal.go +++ b/chore/gogensig/unmarshal/unmarshal.go @@ -23,6 +23,7 @@ func (s FileSet) FindEntry(absIncludePath string) int { return -1 } +// todo(xlj): to improve func (s FileSet) IncludeDir() string { paths := make([]string, 0) includes := make([]string, 0) @@ -32,8 +33,8 @@ func (s FileSet) IncludeDir() string { includes = append(includes, inc.Path) } } - for _, path := range paths { - for _, inc := range includes { + for _, inc := range includes { + for _, path := range paths { after, found := strings.CutSuffix(path, inc) if found { return after From c70f773838ffa5a8d16a241e5b07b4fcfa83d2eb Mon Sep 17 00:00:00 2001 From: tsingbx Date: Wed, 16 Oct 2024 10:29:03 +0800 Subject: [PATCH 5/6] improve IncludeDir function --- chore/gogensig/convert/builtin.go | 3 --- chore/gogensig/convert/package.go | 4 ++++ chore/gogensig/processor/processor.go | 17 +++++------------ chore/gogensig/unmarshal/unmarshal.go | 19 ++++--------------- 4 files changed, 13 insertions(+), 30 deletions(-) diff --git a/chore/gogensig/convert/builtin.go b/chore/gogensig/convert/builtin.go index 79df14e14..5796937ce 100644 --- a/chore/gogensig/convert/builtin.go +++ b/chore/gogensig/convert/builtin.go @@ -109,8 +109,5 @@ func (p *BuiltinTypeMap) initBuiltinTypeMap() { "int64_t": {Type: p.CType("LongLong"), HeaderFile: "sys/_types/_int64_t.h"}, "uint64_t": {Type: p.CType("UlongLong"), HeaderFile: "_types/_uint64_t.h"}, "u_int64_t": {Type: p.CType("UlongLong"), HeaderFile: "sys/_types/_u_int64_t.h"}, - // todo(zzy): undef type log - // other headerfile - //"size_t": {Type: types.Typ[types.Uintptr], HeaderFile: "sys/_types/_u_int64_t.h"}, } } diff --git a/chore/gogensig/convert/package.go b/chore/gogensig/convert/package.go index bd3523179..26e795018 100644 --- a/chore/gogensig/convert/package.go +++ b/chore/gogensig/convert/package.go @@ -153,6 +153,10 @@ func (p *Package) NewFuncDecl(funcDecl *ast.FuncDecl) error { // todo(zzy): for class,union,struct func (p *Package) NewTypeDecl(typeDecl *ast.TypeDecl) error { + if typeDecl.Name == nil { + log.Printf("NewTypeDecl: %s\n", "nil") + return nil + } name := p.cvt.RemovePrefixedName(typeDecl.Name.Name) if _, ok := p.newTypes[name]; ok { return nil diff --git a/chore/gogensig/processor/processor.go b/chore/gogensig/processor/processor.go index 9c7a28927..b4443a11e 100644 --- a/chore/gogensig/processor/processor.go +++ b/chore/gogensig/processor/processor.go @@ -38,22 +38,15 @@ func NewDocFileSetProcessor(docVisitorList []visitor.DocVisitor) *DocFileSetProc p := &DocFileSetProcessor{docVisitorList: docVisitorList} p.visitedFile = make(map[string]struct{}) p.visitedIncludeFile = make(map[string]struct{}) - includes := make([]string, 0) - initIncludes := false p.SetAbsPathFunc(func(s string, fs unmarshal.FileSet) string { - if !initIncludes { - includes = append(includes, fs.IncludeDir()) - initIncludes = true - } if filepath.IsAbs(s) { return s } - for _, includePath := range includes { - absIncludePath := filepath.Join(includePath, s) - _, err := os.Stat(absIncludePath) - if err == nil { - return absIncludePath - } + includePath := fs.IncludeDir(s) + absIncludePath := filepath.Join(includePath, s) + _, err := os.Stat(absIncludePath) + if err == nil { + return absIncludePath } return s }) diff --git a/chore/gogensig/unmarshal/unmarshal.go b/chore/gogensig/unmarshal/unmarshal.go index 7b8c19ee4..8fbcd7afe 100644 --- a/chore/gogensig/unmarshal/unmarshal.go +++ b/chore/gogensig/unmarshal/unmarshal.go @@ -23,22 +23,11 @@ func (s FileSet) FindEntry(absIncludePath string) int { return -1 } -// todo(xlj): to improve -func (s FileSet) IncludeDir() string { - paths := make([]string, 0) - includes := make([]string, 0) +func (s FileSet) IncludeDir(includeFile string) string { for _, f := range s { - paths = append(paths, f.Path) - for _, inc := range f.Doc.Includes { - includes = append(includes, inc.Path) - } - } - for _, inc := range includes { - for _, path := range paths { - after, found := strings.CutSuffix(path, inc) - if found { - return after - } + after, found := strings.CutSuffix(f.Path, includeFile) + if found { + return after } } return "" From 731a707260358067c407993475875295a23283e4 Mon Sep 17 00:00:00 2001 From: tsingbx Date: Sat, 19 Oct 2024 11:21:49 +0800 Subject: [PATCH 6/6] gogensig: add go mod init conf.Name and go get github.com/goplus/llgo --- .gitignore | 4 ++++ chore/gogensig/gogensig.go | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/.gitignore b/.gitignore index e7faa0ecb..e813beb81 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,10 @@ _tinygo/ _output/ build.dir/ .vscode/ +.devcontainer + +*.cfg +*.json # Test binary, built with `go test -c` *.test diff --git a/chore/gogensig/gogensig.go b/chore/gogensig/gogensig.go index fbd51e5ca..26140b048 100644 --- a/chore/gogensig/gogensig.go +++ b/chore/gogensig/gogensig.go @@ -19,6 +19,8 @@ package main import ( "io" "os" + "os/exec" + "path/filepath" "github.com/goplus/llgo/chore/gogensig/config" "github.com/goplus/llgo/chore/gogensig/convert" @@ -27,6 +29,23 @@ import ( "github.com/goplus/llgo/chore/gogensig/visitor" ) +func runCommand(dir, cmdName string, args ...string) error { + execCmd := exec.Command(cmdName, args...) + execCmd.Stdout = os.Stdout + execCmd.Stderr = os.Stderr + execCmd.Dir = dir + return execCmd.Run() +} + +func runGoCmds(pkg string) { + wd, _ := os.Getwd() + dir := filepath.Join(wd, pkg) + os.MkdirAll(dir, 0744) + os.Chdir(pkg) + runCommand(dir, "go", "mod", "init", pkg) + runCommand(dir, "go", "get", "github.com/goplus/llgo") +} + func main() { var data []byte var err error @@ -45,9 +64,12 @@ func main() { data, err = os.ReadFile(sigfetchFile) } check(err) + conf, err := config.GetCppgCfgFromPath("./llcppg.cfg") check(err) + runGoCmds(conf.Name) + astConvert, err := convert.NewAstConvert(&convert.AstConvertConfig{ PkgName: conf.Name, SymbFile: "./llcppg.symb.json", @@ -60,6 +82,7 @@ func main() { err = p.ProcessFileSet(inputdata) check(err) } + func check(err error) { if err != nil { panic(err)