c/clang/symg:abstract common type

This commit is contained in:
luoliwoshang
2024-07-29 11:21:36 +08:00
parent 1e3aef5b94
commit c8532a548c
4 changed files with 50 additions and 58 deletions

View File

@@ -6,7 +6,7 @@ import (
"strconv" "strconv"
"unsafe" "unsafe"
"github.com/goplus/llgo/chore/_xtool/llcppsymg/common" "github.com/goplus/llgo/chore/llcppg/types"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/cjson" "github.com/goplus/llgo/c/cjson"
@@ -16,13 +16,13 @@ import (
type Context struct { type Context struct {
namespaceName string namespaceName string
className string className string
astInfo []common.ASTInformation astInfo []types.ASTInformation
currentFile *c.Char currentFile *c.Char
} }
func newContext() *Context { func newContext() *Context {
return &Context{ return &Context{
astInfo: make([]common.ASTInformation, 0), astInfo: make([]types.ASTInformation, 0),
} }
} }
@@ -40,9 +40,9 @@ func (c *Context) setCurrentFile(filename *c.Char) {
var context = newContext() var context = newContext()
func collectFuncInfo(cursor clang.Cursor) common.ASTInformation { func collectFuncInfo(cursor clang.Cursor) types.ASTInformation {
info := common.ASTInformation{ info := types.ASTInformation{
Namespace: context.namespaceName, Namespace: context.namespaceName,
Class: context.className, Class: context.className,
} }
@@ -73,12 +73,12 @@ func collectFuncInfo(cursor clang.Cursor) common.ASTInformation {
defer typeStr.Dispose() defer typeStr.Dispose()
info.ReturnType = c.GoString(typeStr.CStr()) info.ReturnType = c.GoString(typeStr.CStr())
info.Parameters = make([]common.Parameter, cursor.NumArguments()) info.Parameters = make([]types.Parameter, cursor.NumArguments())
for i := 0; i < int(cursor.NumArguments()); i++ { for i := 0; i < int(cursor.NumArguments()); i++ {
argCurSor := cursor.Argument(c.Uint(i)) argCurSor := cursor.Argument(c.Uint(i))
argType := argCurSor.Type().String() argType := argCurSor.Type().String()
argName := argCurSor.String() argName := argCurSor.String()
info.Parameters[i] = common.Parameter{ info.Parameters[i] = types.Parameter{
Name: c.GoString(argName.CStr()), Name: c.GoString(argName.CStr()),
Type: c.GoString(argType.CStr()), Type: c.GoString(argType.CStr()),
} }
@@ -122,7 +122,7 @@ func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitRe
return clang.ChildVisit_Continue return clang.ChildVisit_Continue
} }
func parse(filenames []*c.Char) []common.ASTInformation { func parse(filenames []*c.Char) []types.ASTInformation {
index := clang.CreateIndex(0, 0) index := clang.CreateIndex(0, 0)
args := make([]*c.Char, 3) args := make([]*c.Char, 3)
args[0] = c.Str("-x") args[0] = c.Str("-x")
@@ -154,7 +154,7 @@ func parse(filenames []*c.Char) []common.ASTInformation {
return context.astInfo return context.astInfo
} }
func printJson(infos []common.ASTInformation) { func printJson(infos []types.ASTInformation) {
root := cjson.Array() root := cjson.Array()
for _, info := range infos { for _, info := range infos {

View File

@@ -1,29 +0,0 @@
package common
type CPPSymbol struct {
Symbol string `json:"symbol"`
Type string `json:"type"`
Name string `json:"name"`
}
type ASTInformation struct {
Namespace string `json:"namespace"`
Class string `json:"class"`
Name string `json:"name"`
BaseClasses []string `json:"baseClasses"`
ReturnType string `json:"returnType"`
Location string `json:"location"`
Parameters []Parameter `json:"parameters"`
Symbol string `json:"symbol"`
}
type Parameter struct {
Name string `json:"name"`
Type string `json:"type"`
}
type SymbolInfo struct {
Mangle string `json:"mangle"` // C++ Symbol
CPP string `json:"c++"` // C++ function name
Go string `json:"go"` // Go function name
}

View File

@@ -30,7 +30,6 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/goplus/llgo/chore/_xtool/llcppsymg/common"
"github.com/goplus/llgo/chore/llcppg/types" "github.com/goplus/llgo/chore/llcppg/types"
) )
@@ -85,7 +84,7 @@ func check(err error) {
} }
} }
func parseDylibSymbols(lib string) ([]common.CPPSymbol, error) { func parseDylibSymbols(lib string) ([]types.CPPSymbol, error) {
dylibPath, _ := generateDylibPath(lib) dylibPath, _ := generateDylibPath(lib)
nmCmd := exec.Command("nm", "-gU", dylibPath) nmCmd := exec.Command("nm", "-gU", dylibPath)
nmOutput, err := nmCmd.Output() nmOutput, err := nmCmd.Output()
@@ -126,9 +125,9 @@ func generateDylibPath(lib string) (string, error) {
return dylibPath, nil return dylibPath, nil
} }
func parseNmOutput(output []byte) []common.CPPSymbol { func parseNmOutput(output []byte) []types.CPPSymbol {
scanner := bufio.NewScanner(bytes.NewReader(output)) scanner := bufio.NewScanner(bytes.NewReader(output))
var symbols []common.CPPSymbol var symbols []types.CPPSymbol
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := scanner.Text()
@@ -138,10 +137,8 @@ func parseNmOutput(output []byte) []common.CPPSymbol {
} }
symbolName := fields[2] symbolName := fields[2]
// Check if the symbol name starts with an underscore and remove it if present // Check if the symbol name starts with an underscore and remove it if present
if strings.HasPrefix(symbolName, "_") { symbolName = strings.TrimPrefix(symbolName, "_")
symbolName = symbolName[1:] symbols = append(symbols, types.CPPSymbol{
}
symbols = append(symbols, common.CPPSymbol{
Symbol: symbolName, Symbol: symbolName,
Type: fields[1], Type: fields[1],
Name: fields[2], Name: fields[2],
@@ -164,7 +161,7 @@ func decodeSymbolName(symbolName string) (string, error) {
} }
// parseHeaderFile // parseHeaderFile
func parseHeaderFile(config types.Config) ([]common.ASTInformation, error) { func parseHeaderFile(config types.Config) ([]types.ASTInformation, error) {
files := generateHeaderFilePath(config.CFlags, config.Include) files := generateHeaderFilePath(config.CFlags, config.Include)
fmt.Println(files) fmt.Println(files)
headerFileCmd := exec.Command("llcppinfofetch", files...) headerFileCmd := exec.Command("llcppinfofetch", files...)
@@ -176,7 +173,7 @@ func parseHeaderFile(config types.Config) ([]common.ASTInformation, error) {
return nil, errors.New("failed to execute header file command") return nil, errors.New("failed to execute header file command")
} }
fmt.Println("headerFileOutput:", string(headerFileOutput), len(headerFileOutput)) fmt.Println("headerFileOutput:", string(headerFileOutput), len(headerFileOutput))
t := make([]common.ASTInformation, 0) t := make([]types.ASTInformation, 0)
err = json.Unmarshal(headerFileOutput, &t) err = json.Unmarshal(headerFileOutput, &t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -186,11 +183,7 @@ func parseHeaderFile(config types.Config) ([]common.ASTInformation, error) {
func generateHeaderFilePath(cflags string, files []string) []string { func generateHeaderFilePath(cflags string, files []string) []string {
prefixPath := expandEnv(cflags) prefixPath := expandEnv(cflags)
if strings.HasPrefix(prefixPath, "-I") { prefixPath = strings.TrimPrefix(prefixPath, "-I")
prefixPath = prefixPath[2:]
}
prefixPath = strings.TrimSpace(prefixPath)
var includePaths []string var includePaths []string
for _, file := range files { for _, file := range files {
includePaths = append(includePaths, filepath.Join(prefixPath, "/"+file)) includePaths = append(includePaths, filepath.Join(prefixPath, "/"+file))
@@ -198,8 +191,8 @@ func generateHeaderFilePath(cflags string, files []string) []string {
return includePaths return includePaths
} }
func getCommonSymbols(dylibSymbols []common.CPPSymbol, astInfoList []common.ASTInformation, prefix []string) []common.SymbolInfo { func getCommonSymbols(dylibSymbols []types.CPPSymbol, astInfoList []types.ASTInformation, prefix []string) []types.SymbolInfo {
var commonSymbols []common.SymbolInfo var commonSymbols []types.SymbolInfo
functionNameMap := make(map[string]int) functionNameMap := make(map[string]int)
for _, astInfo := range astInfoList { for _, astInfo := range astInfoList {
@@ -207,7 +200,7 @@ func getCommonSymbols(dylibSymbols []common.CPPSymbol, astInfoList []common.ASTI
if dylibSym.Symbol == astInfo.Symbol { if dylibSym.Symbol == astInfo.Symbol {
cppName := generateCPPName(astInfo) cppName := generateCPPName(astInfo)
functionNameMap[cppName]++ functionNameMap[cppName]++
symbolInfo := common.SymbolInfo{ symbolInfo := types.SymbolInfo{
Mangle: dylibSym.Symbol, Mangle: dylibSym.Symbol,
CPP: cppName, CPP: cppName,
Go: generateMangle(astInfo, functionNameMap[cppName], prefix), Go: generateMangle(astInfo, functionNameMap[cppName], prefix),
@@ -221,7 +214,7 @@ func getCommonSymbols(dylibSymbols []common.CPPSymbol, astInfoList []common.ASTI
return commonSymbols return commonSymbols
} }
func generateCPPName(astInfo common.ASTInformation) string { func generateCPPName(astInfo types.ASTInformation) string {
cppName := astInfo.Name cppName := astInfo.Name
if astInfo.Class != "" { if astInfo.Class != "" {
cppName = astInfo.Class + "::" + astInfo.Name cppName = astInfo.Class + "::" + astInfo.Name
@@ -229,7 +222,7 @@ func generateCPPName(astInfo common.ASTInformation) string {
return cppName return cppName
} }
func generateMangle(astInfo common.ASTInformation, count int, prefixes []string) string { func generateMangle(astInfo types.ASTInformation, count int, prefixes []string) string {
astInfo.Class = removePrefix(astInfo.Class, prefixes) astInfo.Class = removePrefix(astInfo.Class, prefixes)
astInfo.Name = removePrefix(astInfo.Name, prefixes) astInfo.Name = removePrefix(astInfo.Name, prefixes)
res := "" res := ""

View File

@@ -25,3 +25,31 @@ type Config struct {
TrimPrefixes []string `json:"trimPrefixes"` TrimPrefixes []string `json:"trimPrefixes"`
JSONPath string `json:"jsonPath"` JSONPath string `json:"jsonPath"`
} }
type CPPSymbol struct {
Symbol string `json:"symbol"`
Type string `json:"type"`
Name string `json:"name"`
}
type ASTInformation struct {
Namespace string `json:"namespace"`
Class string `json:"class"`
Name string `json:"name"`
BaseClasses []string `json:"baseClasses"`
ReturnType string `json:"returnType"`
Location string `json:"location"`
Parameters []Parameter `json:"parameters"`
Symbol string `json:"symbol"`
}
type Parameter struct {
Name string `json:"name"`
Type string `json:"type"`
}
type SymbolInfo struct {
Mangle string `json:"mangle"` // C++ Symbol
CPP string `json:"c++"` // C++ function name
Go string `json:"go"` // Go function name
}