From 090e689689b8bef45a9950cf46ff1f0aa6814152 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Mon, 19 Aug 2024 12:07:30 +0800 Subject: [PATCH] llcppsigfetch:basic enum --- chore/_xtool/llcppsigfetch/parse/cvt.go | 52 ++++++- .../parse/cvt_test/decl_test/decl.go | 38 +++++ .../parse/cvt_test/decl_test/llgo.expect | 138 ++++++++++++++++++ chore/_xtool/llcppsigfetch/parse/dump.go | 11 ++ 4 files changed, 235 insertions(+), 4 deletions(-) diff --git a/chore/_xtool/llcppsigfetch/parse/cvt.go b/chore/_xtool/llcppsigfetch/parse/cvt.go index 37aecf9e..07d4efd4 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt.go @@ -164,7 +164,7 @@ func visit(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVi case clang.CursorMacroDefinition: ct.ProcessMarco(cursor) case clang.CursorEnumDecl: - // todo(zzy) + ct.ProcessEnum(cursor) case clang.CursorClassDecl: ct.PushScope(cursor) ct.ProcessClass(cursor) @@ -204,11 +204,12 @@ func (ct *Converter) ProcessType(t clang.Type) ast.Expr { expr = ct.ProcessType(t.CanonicalType()) case clang.TypeConstantArray, clang.TypeIncompleteArray, clang.TypeVariableArray, clang.TypeDependentSizedArray: if t.Kind == clang.TypeConstantArray { - valueStr := make([]c.Char, 20) - c.Sprintf(unsafe.SliceData(valueStr), c.Str("%d"), t.ArraySize()) + len := (*c.Char)(c.Malloc(unsafe.Sizeof(c.Char(0)) * 20)) + c.Sprintf(len, c.Str("%lld"), t.ArraySize()) + defer c.Free(unsafe.Pointer(len)) expr = &ast.ArrayType{ Elt: ct.ProcessType(t.ArrayElementType()), - Len: &ast.BasicLit{Kind: ast.IntLit, Value: c.GoString(unsafe.SliceData(valueStr))}, + Len: &ast.BasicLit{Kind: ast.IntLit, Value: c.GoString(len)}, } } else if t.Kind == clang.TypeIncompleteArray { // incomplete array havent len expr @@ -240,6 +241,49 @@ func (ct *Converter) ProcessFunc(cursor clang.Cursor) *ast.FuncDecl { return fn } +type visitEnumContext struct { + enum *[]*ast.EnumItem + converter *Converter +} + +func visitEnum(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult { + ctx := (*visitEnumContext)(clientData) + if cursor.Kind == clang.CursorEnumConstantDecl { + name := cursor.String() + val := (*c.Char)(c.Malloc(unsafe.Sizeof(c.Char(0)) * 20)) + c.Sprintf(val, c.Str("%lld"), cursor.EnumConstantDeclValue()) + defer c.Free(unsafe.Pointer(val)) + defer name.Dispose() + enum := &ast.EnumItem{ + Name: &ast.Ident{Name: c.GoString(name.CStr())}, + Value: &ast.BasicLit{ + Kind: ast.IntLit, + Value: c.GoString(val), + }, + } + *ctx.enum = append(*ctx.enum, enum) + } + return clang.ChildVisit_Continue +} + +func (ct *Converter) ProcessEnum(cursor clang.Cursor) { + name := cursor.String() + defer name.Dispose() + items := make([]*ast.EnumItem, 0) + ctx := &visitEnumContext{ + enum: &items, + converter: ct, + } + clang.VisitChildren(cursor, visitEnum, c.Pointer(ctx)) + + enum := &ast.EnumTypeDecl{ + DeclBase: ct.CreateDeclBase(cursor), + Name: &ast.Ident{Name: c.GoString(name.CStr())}, + Items: items, + } + ct.curFile.Decls = append(ct.curFile.Decls, enum) +} + // current only collect marco which defined in file func (ct *Converter) ProcessMarco(cursor clang.Cursor) { if ct.curFile == nil { diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go index bba657f6..e9b9a73e 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go @@ -11,6 +11,7 @@ func main() { TestComment() TestStructDecl() TestClassDecl() + TestEnumDecl() } func TestFuncDecl() { @@ -194,3 +195,40 @@ func TestClassDecl() { converter.Dispose() } } + +func TestEnumDecl() { + testCases := []string{ + `enum Foo { + a, + b, + c, + };`, + `enum Foo { + a = 1, + b = 2, + c = 4, + };`, + `enum Foo { + a = 1, + b, + c, + };`, + } + + for i, content := range testCases { + converter, err := parse.NewConverter(content, true) + if err != nil { + panic(err) + } + + _, err = converter.Convert() + if err != nil { + panic(err) + } + + json := converter.MarshalASTFiles() + c.Printf(c.Str("TestEnumDecl Case %d:\n%s\n\n"), c.Int(i+1), json.Print()) + + converter.Dispose() + } +} diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/llgo.expect b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/llgo.expect index 47e9cb36..893bc838 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/llgo.expect +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/llgo.expect @@ -1296,6 +1296,144 @@ TestClassDecl Case 2: } } +TestEnumDecl Case 1: +{ + "temp.h": { + "path": "temp.h", + "decls": [{ + "Loc": { + "File": "temp.h" + }, + "Doc": { + "List": [] + }, + "Parent": null, + "Name": { + "Name": "Foo" + }, + "Items": [{ + "Name": { + "Name": "a" + }, + "Value": { + "Kind": 0, + "Value": "0" + } + }, { + "Name": { + "Name": "b" + }, + "Value": { + "Kind": 0, + "Value": "1" + } + }, { + "Name": { + "Name": "c" + }, + "Value": { + "Kind": 0, + "Value": "2" + } + }] + }], + "includes": [], + "macros": [] + } +} + +TestEnumDecl Case 2: +{ + "temp.h": { + "path": "temp.h", + "decls": [{ + "Loc": { + "File": "temp.h" + }, + "Doc": { + "List": [] + }, + "Parent": null, + "Name": { + "Name": "Foo" + }, + "Items": [{ + "Name": { + "Name": "a" + }, + "Value": { + "Kind": 0, + "Value": "1" + } + }, { + "Name": { + "Name": "b" + }, + "Value": { + "Kind": 0, + "Value": "2" + } + }, { + "Name": { + "Name": "c" + }, + "Value": { + "Kind": 0, + "Value": "4" + } + }] + }], + "includes": [], + "macros": [] + } +} + +TestEnumDecl Case 3: +{ + "temp.h": { + "path": "temp.h", + "decls": [{ + "Loc": { + "File": "temp.h" + }, + "Doc": { + "List": [] + }, + "Parent": null, + "Name": { + "Name": "Foo" + }, + "Items": [{ + "Name": { + "Name": "a" + }, + "Value": { + "Kind": 0, + "Value": "1" + } + }, { + "Name": { + "Name": "b" + }, + "Value": { + "Kind": 0, + "Value": "2" + } + }, { + "Name": { + "Name": "c" + }, + "Value": { + "Kind": 0, + "Value": "3" + } + }] + }], + "includes": [], + "macros": [] + } +} + #stderr diff --git a/chore/_xtool/llcppsigfetch/parse/dump.go b/chore/_xtool/llcppsigfetch/parse/dump.go index 91a9c594..a632a17c 100644 --- a/chore/_xtool/llcppsigfetch/parse/dump.go +++ b/chore/_xtool/llcppsigfetch/parse/dump.go @@ -66,6 +66,14 @@ func MarshalASTDecl(decl ast.Decl) *cjson.JSON { } root := cjson.Object() switch d := decl.(type) { + case *ast.EnumTypeDecl: + MarshalASTDeclBase(d.DeclBase, root) + root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name)) + items := cjson.Array() + for _, i := range d.Items { + items.AddItem(MarshalASTExpr(i)) + } + root.SetItem(c.Str("Items"), items) case *ast.FuncDecl: MarshalASTDeclBase(d.DeclBase, root) root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name)) @@ -123,6 +131,9 @@ func MarshalASTExpr(t ast.Expr) *cjson.JSON { root.SetItem(c.Str("Names"), names) case *ast.Ident: root.SetItem(c.Str("Name"), cjson.String(c.AllocaCStr(d.Name))) + case *ast.EnumItem: + root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name)) + root.SetItem(c.Str("Value"), MarshalASTExpr(d.Value)) case *ast.BasicLit: root.SetItem(c.Str("Kind"), cjson.Number(float64(d.Kind))) root.SetItem(c.Str("Value"), cjson.String(c.AllocaCStr(d.Value)))