llcppsymg:use clang's displayname with semantic parent to construct func proto for c/c++

This commit is contained in:
luoliwoshang
2024-09-09 14:24:36 +08:00
parent 4688434c08
commit 78f0177ac4
3 changed files with 45 additions and 23 deletions

View File

@@ -70,3 +70,16 @@ func CreateTranslationUnit(config *Config) (*clang.Index, *clang.TranslationUnit
return index, unit, nil 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
}

View File

@@ -30,7 +30,6 @@ import (
"github.com/goplus/llgo/chore/_xtool/llcppsymg/config" "github.com/goplus/llgo/chore/_xtool/llcppsymg/config"
"github.com/goplus/llgo/chore/_xtool/llcppsymg/parse" "github.com/goplus/llgo/chore/_xtool/llcppsymg/parse"
"github.com/goplus/llgo/chore/llcppg/types" "github.com/goplus/llgo/chore/llcppg/types"
"github.com/goplus/llgo/cpp/llvm"
"github.com/goplus/llgo/xtool/nm" "github.com/goplus/llgo/xtool/nm"
) )
@@ -115,19 +114,6 @@ func genDylibPath(lib string) (string, error) {
return dylibPath, nil 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 { func genHeaderFilePath(cflags string, files []string) []string {
prefixPath := cflags prefixPath := cflags
prefixPath = strings.TrimPrefix(prefixPath, "-I") prefixPath = strings.TrimPrefix(prefixPath, "-I")
@@ -138,15 +124,15 @@ func genHeaderFilePath(cflags string, files []string) []string {
return includePaths 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 var commonSymbols []*types.SymbolInfo
for _, dylibSym := range dylibSymbols { for _, dylibSym := range dylibSymbols {
symName := strings.TrimPrefix(dylibSym.Name, "_") symName := strings.TrimPrefix(dylibSym.Name, "_")
if goName, ok := symbolMap[symName]; ok { if symInfo, ok := symbolMap[symName]; ok {
symbolInfo := &types.SymbolInfo{ symbolInfo := &types.SymbolInfo{
Mangle: symName, Mangle: symName,
CPP: decodeSymbol(dylibSym.Name), CPP: symInfo.ProtoName,
Go: goName, Go: symInfo.GoName,
} }
commonSymbols = append(commonSymbols, symbolInfo) commonSymbols = append(commonSymbols, symbolInfo)
} }

View File

@@ -10,11 +10,16 @@ import (
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils" "github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
) )
type SymbolInfo struct {
GoName string
ProtoName string
}
type Context struct { type Context struct {
namespaceName string namespaceName string
className string className string
prefixes []string prefixes []string
symbolMap map[string]string symbolMap map[string]*SymbolInfo
currentFile string currentFile string
nameCounts map[string]int nameCounts map[string]int
} }
@@ -22,7 +27,7 @@ type Context struct {
func newContext(prefixes []string) *Context { func newContext(prefixes []string) *Context {
return &Context{ return &Context{
prefixes: prefixes, prefixes: prefixes,
symbolMap: make(map[string]string), symbolMap: make(map[string]*SymbolInfo),
nameCounts: make(map[string]int), nameCounts: make(map[string]int),
} }
} }
@@ -73,6 +78,22 @@ func (c *Context) genMethodName(class, name string) string {
return prefix + name 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 { func (c *Context) addSuffix(name string) string {
c.nameCounts[name]++ c.nameCounts[name]++
count := c.nameCounts[name] count := c.nameCounts[name]
@@ -96,8 +117,10 @@ func collectFuncInfo(cursor clang.Cursor) {
defer symbol.Dispose() defer symbol.Dispose()
defer cursorStr.Dispose() defer cursorStr.Dispose()
goName := context.genGoName(name) context.symbolMap[symbolName] = &SymbolInfo{
context.symbolMap[symbolName] = goName GoName: context.genGoName(name),
ProtoName: context.genProtoName(cursor),
}
} }
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult { 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 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) context = newContext(prefixes)
index := clang.CreateIndex(0, 0) index := clang.CreateIndex(0, 0)
for _, filename := range filepaths { for _, filename := range filepaths {