llcppsigfetch:basic enum
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)))
|
||||
|
||||
Reference in New Issue
Block a user