llcppsigfetch:collect func param name

This commit is contained in:
luoliwoshang
2024-08-13 18:35:33 +08:00
parent 1996db4b95
commit 755cdbb238
3 changed files with 319 additions and 35 deletions

View File

@@ -142,14 +142,9 @@ func (ct *Converter) ProcessType(t clang.Type) ast.Expr {
case clang.TypePointer:
expr = &ast.PointerType{X: ct.ProcessType(t.PointeeType())}
case clang.TypeFunctionProto:
// function type will only collect return type, params will be collected in ProcessFunc
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}
expr = &ast.FuncType{Ret: ret}
case clang.TypeTypedef:
expr = ct.ProcessType(t.CanonicalType())
case clang.TypeConstantArray, clang.TypeVariableArray, clang.TypeIncompleteArray, clang.TypeDependentSizedArray:
@@ -164,11 +159,16 @@ func (ct *Converter) ProcessType(t clang.Type) ast.Expr {
func (ct *Converter) ProcessFunc(cursor clang.Cursor) {
name := cursor.String()
defer name.Dispose()
// function type will only collect return type
// ProcessType can't get the field names,will collect in follows
funcType, ok := ct.ProcessType(cursor.Type()).(*ast.FuncType)
if !ok {
fmt.Println("failed to process function type")
return
}
params := ct.ProcessFuncParams(cursor)
funcType.Params = params
fn := &ast.FuncDecl{
Name: &ast.Ident{Name: c.GoString(name.CStr())},
Type: funcType,
@@ -178,6 +178,42 @@ func (ct *Converter) ProcessFunc(cursor clang.Cursor) {
// ct.declMap[cursor] = fn
}
type visitParamContext struct {
params *ast.FieldList
converter *Converter
}
// visit top decls (struct,class,function,enum & marco,include)
func visitParamDecl(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
ctx := (*visitParamContext)(clientData)
if cursor.Kind == clang.CursorParmDecl {
paramName := cursor.String()
defer paramName.Dispose()
argType := ctx.converter.ProcessType(cursor.Type())
// In C language, parameter lists do not have similar parameter grouping in Go.
// func foo(a, b int)
ctx.params.List = append(ctx.params.List,
&ast.Field{
Type: argType,
Names: []*ast.Ident{
{Name: c.GoString(paramName.CStr())},
},
})
}
return clang.ChildVisit_Continue
}
func (ct *Converter) ProcessFuncParams(cursor clang.Cursor) *ast.FieldList {
params := &ast.FieldList{List: []*ast.Field{}}
ctx := &visitParamContext{
params: params,
converter: ct,
}
clang.VisitChildren(cursor, visitParamDecl, c.Pointer(ctx))
return params
}
func (ct *Converter) ProcessClass(cursor clang.Cursor) {
println("todo: Process class")
}

View File

@@ -10,17 +10,30 @@ func main() {
}
func TestFuncDecl() {
content := `int foo(int a, int b);`
converter, err := parse.NewConverter(content, true)
if err != nil {
panic(err)
testCases := []string{
`void foo();`,
`void foo(int a);`,
`float foo(int a,double b);`,
`void foo(char* str, double x);`,
`float* foo(char* str, double x);`,
`float* foo(char*** str, double x);`,
}
defer converter.Dispose()
converter.Convert()
if err != nil {
panic(err)
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.GetFilesJSON()
c.Printf(c.Str("Test Case %d:\n%s\n\n"), c.Int(i+1), json.Print())
converter.Dispose()
}
json := converter.GetFilesJSON()
c.Printf(c.Str("%s\n"), json.Print())
}

View File

@@ -1,30 +1,265 @@
#stdout
Test Case 1:
{
"Files": {
"temp.h": {
"Path": "temp.h",
"decls": [{
"Name": "foo",
"Type": {
"Params": [{
"Kind": 6,
"Flags": 0
"temp.h": {
"Path": "temp.h",
"decls": [{
"Loc": null,
"Doc": null,
"Parent": null,
"Name": {
"Name": "foo"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
}
}],
"includes": [],
"macros": []
}
}
Test Case 2:
{
"temp.h": {
"Path": "temp.h",
"decls": [{
"Loc": null,
"Doc": null,
"Parent": null,
"Name": {
"Name": "foo"
},
"Type": {
"Params": {
"List": [{
"Type": {
"Kind": 6,
"Flags": 0
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "a"
}]
}]
},
"Ret": {
"Kind": 0,
"Flags": 0
}
}
}],
"includes": [],
"macros": []
}
}
Test Case 3:
{
"temp.h": {
"Path": "temp.h",
"decls": [{
"Loc": null,
"Doc": null,
"Parent": null,
"Name": {
"Name": "foo"
},
"Type": {
"Params": {
"List": [{
"Type": {
"Kind": 6,
"Flags": 0
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "a"
}]
}, {
"Kind": 6,
"Flags": 0
}],
"Ret": {
"Kind": 6,
"Type": {
"Kind": 8,
"Flags": 16
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "b"
}]
}]
},
"Ret": {
"Kind": 8,
"Flags": 0
}
}
}],
"includes": [],
"macros": []
}
}
Test Case 4:
{
"temp.h": {
"Path": "temp.h",
"decls": [{
"Loc": null,
"Doc": null,
"Parent": null,
"Name": {
"Name": "foo"
},
"Type": {
"Params": {
"List": [{
"Type": {
"X": {
"Kind": 2,
"Flags": 1
}
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "str"
}]
}, {
"Type": {
"Kind": 8,
"Flags": 16
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "x"
}]
}]
},
"Ret": {
"Kind": 0,
"Flags": 0
}
}
}],
"includes": [],
"macros": []
}
}
Test Case 5:
{
"temp.h": {
"Path": "temp.h",
"decls": [{
"Loc": null,
"Doc": null,
"Parent": null,
"Name": {
"Name": "foo"
},
"Type": {
"Params": {
"List": [{
"Type": {
"X": {
"Kind": 2,
"Flags": 1
}
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "str"
}]
}, {
"Type": {
"Kind": 8,
"Flags": 16
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "x"
}]
}]
},
"Ret": {
"X": {
"Kind": 8,
"Flags": 0
}
}
}],
"includes": [],
"macros": []
}
}
}],
"includes": [],
"macros": []
}
}
Test Case 6:
{
"temp.h": {
"Path": "temp.h",
"decls": [{
"Loc": null,
"Doc": null,
"Parent": null,
"Name": {
"Name": "foo"
},
"Type": {
"Params": {
"List": [{
"Type": {
"X": {
"X": {
"X": {
"Kind": 2,
"Flags": 1
}
}
}
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "str"
}]
}, {
"Type": {
"Kind": 8,
"Flags": 16
},
"Doc": null,
"Comment": null,
"Names": [{
"Name": "x"
}]
}]
},
"Ret": {
"X": {
"Kind": 8,
"Flags": 0
}
}
}
}],
"includes": [],
"macros": []
}
}
#stderr
#exit 0