diff --git a/chore/_xtool/llcppsigfetch/parse/cvt.go b/chore/_xtool/llcppsigfetch/parse/cvt.go index 806db4ee..ac04b414 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt.go @@ -12,11 +12,13 @@ import ( type Converter struct { files map[string]*ast.File - typeMap map[clang.Type]*ast.Expr - declMap map[clang.Cursor]*ast.Decl + typeMap map[clang.Type]ast.Expr // todo(zzy):maybe a other map key for typemap is better + declMap map[clang.Cursor]ast.Decl curLoc ast.Location + curFile *ast.File index *clang.Index unit *clang.TranslationUnit + // todo(zzy):current namespace expr } func NewConverter(filepath string) (*Converter, error) { @@ -37,8 +39,8 @@ func NewConverter(filepath string) (*Converter, error) { } return &Converter{ - typeMap: make(map[clang.Type]*ast.Expr), - declMap: make(map[clang.Cursor]*ast.Decl), + typeMap: make(map[clang.Type]ast.Expr), + declMap: make(map[clang.Cursor]ast.Decl), files: make(map[string]*ast.File), index: index, unit: unit, @@ -52,6 +54,7 @@ func (ct *Converter) Dispose() { // visit top decls (struct,class,function,enum & marco,include) func visit(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult { + // todo(zzy): set current file ct := (*Converter)(clientData) switch cursor.Kind { case clang.CursorInclusionDirective: @@ -78,8 +81,56 @@ func visit(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVi } } +func (ct *Converter) ProcessType(t clang.Type) ast.Expr { + // todo(zzy):a other map key for typemap + if cache, ok := ct.typeMap[t]; ok { + return cache + } + var expr ast.Expr + switch t.Kind { + case clang.TypePointer: + expr = &ast.PointerType{X: ct.ProcessType(t.PointeeType())} + case clang.TypeFunctionProto: + ret := ct.ProcessType(t.ResultType()) + params := &ast.FieldList{} + for i := 0; i < int(t.NumArgTypes()); i++ { + argType := ct.ProcessType(t.ArgType(c.Uint(i))) + params.List = append(params.List, &ast.Field{Type: argType}) + // todo(zzy):field name + } + expr = &ast.FuncType{Params: params, Ret: ret} + case clang.TypeTypedef: + expr = ct.ProcessType(t.CanonicalType()) + case clang.TypeConstantArray, clang.TypeVariableArray, clang.TypeIncompleteArray, clang.TypeDependentSizedArray: + expr = &ast.ArrayType{ + Elt: ct.ProcessType(t.ArrayElementType()), + } + // todo(zzy):array length + } + ct.typeMap[t] = expr + return expr +} + func (ct *Converter) ProcessFunc(cursor clang.Cursor) { - println("todo: Process func") + name := cursor.String() + defer name.Dispose() + + funcType, ok := ct.ProcessType(cursor.Type()).(*ast.FuncType) + if !ok { + fmt.Println("failed to process function type") + return + } + + fn := &ast.FuncDecl{ + Name: &ast.Ident{Name: c.GoString(name.CStr())}, + Type: funcType, + // todo(zzy):DeclBase use the converter's current namespace expr + } + + decls := ct.GetCurFile() + decls.Decls = append(decls.Decls, fn) + + ct.declMap[cursor] = fn } func (ct *Converter) ProcessClass(cursor clang.Cursor) { @@ -96,3 +147,7 @@ func (ct *Converter) Convert() (map[string]*ast.File, error) { func (ct *Converter) UpdateLocation(loc ast.Location) { ct.curLoc = loc } + +func (ct *Converter) GetCurFile() *ast.File { + return ct.curFile +}