llcppsigfetch:out of class method

This commit is contained in:
luoliwoshang
2024-08-26 18:43:38 +08:00
parent fc04083cb2
commit b524472b9e
3 changed files with 94 additions and 1 deletions

View File

@@ -208,7 +208,9 @@ func visitTop(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.Chil
case clang.CursorUnionDecl: case clang.CursorUnionDecl:
unionDecl := ct.ProcessUnionDecl(cursor) unionDecl := ct.ProcessUnionDecl(cursor)
curFile.Decls = append(curFile.Decls, unionDecl) curFile.Decls = append(curFile.Decls, unionDecl)
case clang.CursorFunctionDecl: case clang.CursorFunctionDecl, clang.CursorCXXMethod, clang.CursorConstructor, clang.CursorDestructor:
// Handle functions and class methods (including out-of-class method)
// Example: void MyClass::myMethod() { ... } out-of-class method
curFile.Decls = append(curFile.Decls, ct.ProcessFuncDecl(cursor)) curFile.Decls = append(curFile.Decls, ct.ProcessFuncDecl(cursor))
case clang.CursorTypedefDecl: case clang.CursorTypedefDecl:
curFile.Decls = append(curFile.Decls, ct.ProcessTypeDefDecl(cursor)) curFile.Decls = append(curFile.Decls, ct.ProcessTypeDefDecl(cursor))
@@ -276,6 +278,7 @@ func (ct *Converter) ProcessTypeDefDecl(cursor clang.Cursor) *ast.TypedefDecl {
} }
} }
// converts functions, methods, constructors, destructors (including out-of-class decl) to ast.FuncDecl nodes.
func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl { func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
name := cursor.String() name := cursor.String()
defer name.Dispose() defer name.Dispose()
@@ -301,6 +304,11 @@ func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
} }
if isMethod(cursor) { if isMethod(cursor) {
if parent := cursor.SemanticParent(); parent.Equal(cursor.LexicalParent()) != 1 {
fn.DeclBase.Parent = qualifiedExpr(buildQualifiedName(cursor))
}
if cursor.Kind == clang.CursorDestructor { if cursor.Kind == clang.CursorDestructor {
fn.IsDestructor = true fn.IsDestructor = true
} }
@@ -657,6 +665,22 @@ func isMethod(cursor clang.Cursor) bool {
return cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor return cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor
} }
func buildQualifiedName(cursor clang.Cursor) string {
var parts []string
cursor = cursor.SemanticParent()
// Traverse up the semantic parents
for cursor.IsNull() != 1 && cursor.Kind != clang.CursorTranslationUnit {
name := cursor.String()
qualified := c.GoString(name.CStr())
parts = append([]string{qualified}, parts...)
cursor = cursor.SemanticParent()
name.Dispose()
}
return strings.Join(parts, "::")
}
func qualifiedExpr(name string) ast.Expr { func qualifiedExpr(name string) ast.Expr {
parts := strings.Split(name, "::") parts := strings.Split(name, "::")
var expr ast.Expr = &ast.Ident{Name: parts[0]} var expr ast.Expr = &ast.Ident{Name: parts[0]}

View File

@@ -41,6 +41,11 @@ func TestClassDecl() {
void foo() override; void foo() override;
}; };
`, `,
`namespace A{
class Foo{}
}
void A::Foo::bar();
`,
} }
test.RunTest("TestClassDecl", testCases) test.RunTest("TestClassDecl", testCases)
} }

View File

@@ -539,6 +539,70 @@ TestClassDecl Case 4:
} }
} }
TestClassDecl Case 5:
{
"temp.h": {
"decls": [{
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "A"
},
"Name": {
"Name": "Foo"
},
"Type": {
"Tag": 3,
"Fields": {
"List": []
},
"Methods": []
}
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"X": {
"Name": "Foo"
},
"Parent": {
"Name": "A"
}
},
"Name": {
"Name": "bar"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}],
"includes": [],
"macros": []
}
}
#stderr #stderr