From 78f0177ac4859cd785e1f0f5b1ca5f0a0d9af983 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Mon, 9 Sep 2024 14:24:36 +0800 Subject: [PATCH] llcppsymg:use clang's displayname with semantic parent to construct func proto for c/c++ --- .../_xtool/llcppsymg/clangutils/clangutils.go | 13 ++++++++ chore/_xtool/llcppsymg/llcppsymg.go | 22 +++---------- chore/_xtool/llcppsymg/parse/parse.go | 33 ++++++++++++++++--- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/chore/_xtool/llcppsymg/clangutils/clangutils.go b/chore/_xtool/llcppsymg/clangutils/clangutils.go index c03281dd..95681d25 100644 --- a/chore/_xtool/llcppsymg/clangutils/clangutils.go +++ b/chore/_xtool/llcppsymg/clangutils/clangutils.go @@ -70,3 +70,16 @@ func CreateTranslationUnit(config *Config) (*clang.Index, *clang.TranslationUnit return index, unit, nil } + +// Traverse up the semantic parents +func BuildScopingParts(cursor clang.Cursor) []string { + var parts []string + for cursor.IsNull() != 1 && cursor.Kind != clang.CursorTranslationUnit { + name := cursor.String() + qualified := c.GoString(name.CStr()) + parts = append([]string{qualified}, parts...) + cursor = cursor.SemanticParent() + name.Dispose() + } + return parts +} diff --git a/chore/_xtool/llcppsymg/llcppsymg.go b/chore/_xtool/llcppsymg/llcppsymg.go index cfc842e5..e9e0dc78 100644 --- a/chore/_xtool/llcppsymg/llcppsymg.go +++ b/chore/_xtool/llcppsymg/llcppsymg.go @@ -30,7 +30,6 @@ import ( "github.com/goplus/llgo/chore/_xtool/llcppsymg/config" "github.com/goplus/llgo/chore/_xtool/llcppsymg/parse" "github.com/goplus/llgo/chore/llcppg/types" - "github.com/goplus/llgo/cpp/llvm" "github.com/goplus/llgo/xtool/nm" ) @@ -115,19 +114,6 @@ func genDylibPath(lib string) (string, error) { return dylibPath, nil } -func decodeSymbol(symbolName string) string { - if symbolName == "" { - return "" - } - demangled := llvm.ItaniumDemangle(symbolName, true) - if demangled == nil { - return symbolName - } - defer c.Free(unsafe.Pointer(demangled)) - demangleName := c.GoString(demangled) - return strings.TrimSpace(demangleName) -} - func genHeaderFilePath(cflags string, files []string) []string { prefixPath := cflags prefixPath = strings.TrimPrefix(prefixPath, "-I") @@ -138,15 +124,15 @@ func genHeaderFilePath(cflags string, files []string) []string { return includePaths } -func getCommonSymbols(dylibSymbols []*nm.Symbol, symbolMap map[string]string, prefix []string) []*types.SymbolInfo { +func getCommonSymbols(dylibSymbols []*nm.Symbol, symbolMap map[string]*parse.SymbolInfo, prefix []string) []*types.SymbolInfo { var commonSymbols []*types.SymbolInfo for _, dylibSym := range dylibSymbols { symName := strings.TrimPrefix(dylibSym.Name, "_") - if goName, ok := symbolMap[symName]; ok { + if symInfo, ok := symbolMap[symName]; ok { symbolInfo := &types.SymbolInfo{ Mangle: symName, - CPP: decodeSymbol(dylibSym.Name), - Go: goName, + CPP: symInfo.ProtoName, + Go: symInfo.GoName, } commonSymbols = append(commonSymbols, symbolInfo) } diff --git a/chore/_xtool/llcppsymg/parse/parse.go b/chore/_xtool/llcppsymg/parse/parse.go index 55abd1a9..88ff1b4a 100644 --- a/chore/_xtool/llcppsymg/parse/parse.go +++ b/chore/_xtool/llcppsymg/parse/parse.go @@ -10,11 +10,16 @@ import ( "github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils" ) +type SymbolInfo struct { + GoName string + ProtoName string +} + type Context struct { namespaceName string className string prefixes []string - symbolMap map[string]string + symbolMap map[string]*SymbolInfo currentFile string nameCounts map[string]int } @@ -22,7 +27,7 @@ type Context struct { func newContext(prefixes []string) *Context { return &Context{ prefixes: prefixes, - symbolMap: make(map[string]string), + symbolMap: make(map[string]*SymbolInfo), nameCounts: make(map[string]int), } } @@ -73,6 +78,22 @@ func (c *Context) genMethodName(class, name string) string { return prefix + name } +func (p *Context) genProtoName(cursor clang.Cursor) string { + displayName := cursor.DisplayName() + defer displayName.Dispose() + + scopingParts := clangutils.BuildScopingParts(cursor.SemanticParent()) + + var builder strings.Builder + for _, part := range scopingParts { + builder.WriteString(part) + builder.WriteString("::") + } + + builder.WriteString(c.GoString(displayName.CStr())) + return builder.String() +} + func (c *Context) addSuffix(name string) string { c.nameCounts[name]++ count := c.nameCounts[name] @@ -96,8 +117,10 @@ func collectFuncInfo(cursor clang.Cursor) { defer symbol.Dispose() defer cursorStr.Dispose() - goName := context.genGoName(name) - context.symbolMap[symbolName] = goName + context.symbolMap[symbolName] = &SymbolInfo{ + GoName: context.genGoName(name), + ProtoName: context.genProtoName(cursor), + } } func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult { @@ -133,7 +156,7 @@ func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitRe return clang.ChildVisit_Continue } -func ParseHeaderFile(filepaths []string, prefixes []string, isCpp bool) (map[string]string, error) { +func ParseHeaderFile(filepaths []string, prefixes []string, isCpp bool) (map[string]*SymbolInfo, error) { context = newContext(prefixes) index := clang.CreateIndex(0, 0) for _, filename := range filepaths {