llcppsigfetch:basic enum

This commit is contained in:
luoliwoshang
2024-08-19 12:07:30 +08:00
parent 9d16df5f25
commit 090e689689
4 changed files with 235 additions and 4 deletions

View File

@@ -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 {

View File

@@ -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()
}
}

View File

@@ -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

View File

@@ -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)))