From 9351a1f9000c28e10159246f7c2562d711c32ed1 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Tue, 27 Aug 2024 18:50:51 +0800 Subject: [PATCH] llcppsigfetch:anonymous elaborated type refer --- chore/_xtool/llcppsigfetch/parse/cvt.go | 52 ++++++--- .../decl_test/struct_test/llgo.expect | 100 ++++++++++++++++++ .../cvt_test/decl_test/struct_test/struct.go | 8 ++ .../cvt_test/decl_test/union_test/llgo.expect | 100 ++++++++++++++++++ .../cvt_test/decl_test/union_test/union.go | 8 ++ .../parse/cvt_test/type_test/llgo.expect | 78 ++++++++++++++ .../parse/cvt_test/type_test/type.go | 14 ++- 7 files changed, 346 insertions(+), 14 deletions(-) diff --git a/chore/_xtool/llcppsigfetch/parse/cvt.go b/chore/_xtool/llcppsigfetch/parse/cvt.go index 842c5bd6..9ce3af3d 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt.go @@ -372,22 +372,26 @@ func visitEnum(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.Chi return clang.ChildVisit_Continue } -func (ct *Converter) ProcessEnumDecl(cursor clang.Cursor) *ast.EnumTypeDecl { - name := cursor.String() - defer name.Dispose() +func (ct *Converter) ProcessEnumType(cursor clang.Cursor) *ast.EnumType { items := make([]*ast.EnumItem, 0) ctx := &visitEnumContext{ enum: &items, converter: ct, } clang.VisitChildren(cursor, visitEnum, c.Pointer(ctx)) + return &ast.EnumType{ + Items: items, + } +} + +func (ct *Converter) ProcessEnumDecl(cursor clang.Cursor) *ast.EnumTypeDecl { + name := cursor.String() + defer name.Dispose() return &ast.EnumTypeDecl{ DeclBase: ct.CreateDeclBase(cursor), Name: &ast.Ident{Name: c.GoString(name.CStr())}, - Type: &ast.EnumType{ - Items: items, - }, + Type: ct.ProcessEnumType(cursor), } } @@ -501,7 +505,7 @@ func (ct *Converter) ProcessMethods(cursor clang.Cursor) []*ast.FuncDecl { return methods } -func (ct *Converter) ProcessRecordDecl(cursor clang.Cursor, tag ast.Tag) *ast.TypeDecl { +func (ct *Converter) ProcessRecordDecl(cursor clang.Cursor) *ast.TypeDecl { anony := cursor.IsAnonymousRecordDecl() var name *ast.Ident @@ -514,23 +518,23 @@ func (ct *Converter) ProcessRecordDecl(cursor clang.Cursor, tag ast.Tag) *ast.Ty return &ast.TypeDecl{ DeclBase: ct.CreateDeclBase(cursor), Name: name, - Type: ct.ProcessRecordType(cursor, tag), + Type: ct.ProcessRecordType(cursor), } } func (ct *Converter) ProcessStructDecl(cursor clang.Cursor) *ast.TypeDecl { - return ct.ProcessRecordDecl(cursor, ast.Struct) + return ct.ProcessRecordDecl(cursor) } func (ct *Converter) ProcessUnionDecl(cursor clang.Cursor) *ast.TypeDecl { - return ct.ProcessRecordDecl(cursor, ast.Union) + return ct.ProcessRecordDecl(cursor) } func (ct *Converter) ProcessClassDecl(cursor clang.Cursor) *ast.TypeDecl { // Pushing class scope before processing its type and popping after base := ct.CreateDeclBase(cursor) - typ := ct.ProcessRecordType(cursor, ast.Class) + typ := ct.ProcessRecordType(cursor) return &ast.TypeDecl{ DeclBase: base, @@ -539,18 +543,40 @@ func (ct *Converter) ProcessClassDecl(cursor clang.Cursor) *ast.TypeDecl { } } -func (ct *Converter) ProcessRecordType(cursor clang.Cursor, tag ast.Tag) *ast.RecordType { +func (ct *Converter) ProcessRecordType(cursor clang.Cursor) *ast.RecordType { + tagMap := map[clang.CursorKind]ast.Tag{ + clang.CursorStructDecl: ast.Struct, + clang.CursorUnionDecl: ast.Union, + clang.CursorClassDecl: ast.Class, + } return &ast.RecordType{ - Tag: tag, + Tag: tagMap[cursor.Kind], Fields: ct.ProcessFieldList(cursor), Methods: ct.ProcessMethods(cursor), } } +// process ElaboratedType Reference +// +// 1. Named elaborated type references: +// - Examples: struct MyStruct, union MyUnion, class MyClass, enum MyEnum +// - Handling: Constructed as TagExpr or ScopingExpr references +// +// 2. Anonymous elaborated type references: +// - Examples: struct { int x; int y; }, union { int a; float b; } +// - Handling: Retrieve their corresponding concrete types func (ct *Converter) ProcessElaboratedType(t clang.Type) ast.Expr { name := t.String() defer name.Dispose() + decl := t.TypeDeclaration() + if decl.IsAnonymous() != 0 { + if decl.Kind == clang.CursorEnumDecl { + return ct.ProcessEnumType(decl) + } + return ct.ProcessRecordType(decl) + } + typeName := c.GoString(name.CStr()) tagMap := map[string]ast.Tag{ diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/struct_test/llgo.expect b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/struct_test/llgo.expect index 8d208c32..f3021595 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/struct_test/llgo.expect +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/struct_test/llgo.expect @@ -226,6 +226,106 @@ TestStructDecl Case 4: } } +TestStructDecl Case 5: +{ + "temp.h": { + "decls": [{ + "Loc": { + "File": "temp.h" + }, + "Doc": { + "List": [] + }, + "Parent": null, + "Name": { + "Name": "Person" + }, + "Type": { + "Tag": 0, + "Fields": { + "List": [{ + "Type": { + "Kind": 6, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "age" + }] + }, { + "Type": { + "Tag": 0, + "Fields": { + "List": [{ + "Type": { + "Kind": 6, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "year" + }] + }, { + "Type": { + "Kind": 6, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "day" + }] + }, { + "Type": { + "Kind": 6, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "month" + }] + }] + }, + "Methods": [] + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "birthday" + }] + }] + }, + "Methods": [] + } + }], + "includes": [], + "macros": [] + } +} + #stderr diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/struct_test/struct.go b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/struct_test/struct.go index 6e05aae3..39d40d8c 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/struct_test/struct.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/struct_test/struct.go @@ -22,6 +22,14 @@ func TestStructDecl() { int a; int (*Foo)(int, int); };`, + `struct Person { + int age; + struct { + int year; + int day; + int month; + } birthday; + };`, } test.RunTest("TestStructDecl", testCases) } diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/union_test/llgo.expect b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/union_test/llgo.expect index 7c0943df..07db788f 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/union_test/llgo.expect +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/union_test/llgo.expect @@ -107,6 +107,106 @@ TestUnionDecl Case 2: } } +TestUnionDecl Case 3: +{ + "temp.h": { + "decls": [{ + "Loc": { + "File": "temp.h" + }, + "Doc": { + "List": [] + }, + "Parent": null, + "Name": { + "Name": "OuterUnion" + }, + "Type": { + "Tag": 1, + "Fields": { + "List": [{ + "Type": { + "Kind": 6, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "i" + }] + }, { + "Type": { + "Kind": 8, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "f" + }] + }, { + "Type": { + "Tag": 1, + "Fields": { + "List": [{ + "Type": { + "Kind": 2, + "Flags": 1 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "c" + }] + }, { + "Type": { + "Kind": 6, + "Flags": 32 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "s" + }] + }] + }, + "Methods": [] + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "inner" + }] + }] + }, + "Methods": [] + } + }], + "includes": [], + "macros": [] + } +} + #stderr diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/union_test/union.go b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/union_test/union.go index 1f5f7942..5e8c18b5 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/union_test/union.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/union_test/union.go @@ -16,6 +16,14 @@ func TestUnionDecl() { int a; int b; };`, + `union OuterUnion { + int i; + float f; + union { + char c; + short s; + } inner; + };`, } test.RunTest("TestUnionDecl", testCases) } diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/llgo.expect b/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/llgo.expect index 7adead79..443dab45 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/llgo.expect +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/llgo.expect @@ -105,6 +105,28 @@ Type: struct Foo: }, "Tag": 0 } +Type: struct (unnamed struct at temp.h:1:1): +{ + "Tag": 0, + "Fields": { + "List": [{ + "Type": { + "Kind": 6, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "x" + }] + }] + }, + "Methods": [] +} Type: Foo: { "Name": "Foo" @@ -116,6 +138,28 @@ Type: union Foo: }, "Tag": 1 } +Type: union (unnamed union at temp.h:1:1): +{ + "Tag": 1, + "Fields": { + "List": [{ + "Type": { + "Kind": 6, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "x" + }] + }] + }, + "Methods": [] +} Type: Foo: { "Name": "Foo" @@ -127,6 +171,18 @@ Type: enum Foo: }, "Tag": 2 } +Type: enum (unnamed enum at temp.h:1:1): +{ + "Items": [{ + "Name": { + "Name": "x" + }, + "Value": { + "Kind": 0, + "Value": "42" + } + }] +} Type: Foo: { "Name": "Foo" @@ -138,6 +194,28 @@ Type: class Foo: }, "Tag": 3 } +Type: class (unnamed class at temp.h:1:1): +{ + "Tag": 3, + "Fields": { + "List": [{ + "Type": { + "Kind": 6, + "Flags": 0 + }, + "Doc": { + "List": [] + }, + "Comment": { + "List": [] + }, + "Names": [{ + "Name": "x" + }] + }] + }, + "Methods": [] +} Type: a::b::c: { "X": { diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/type.go b/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/type.go index 789dfa3c..3d33814e 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/type.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/type.go @@ -80,21 +80,31 @@ func TestNonBuiltinTypes() { Foo`, `struct Foo {}; struct Foo`, + `struct { + int x; + }`, `union Foo {}; Foo`, `union Foo {}; union Foo`, + `union { + int x; + }`, `enum Foo {}; Foo`, `enum Foo {}; enum Foo`, + `enum { x = 42 }`, `class Foo {}; Foo`, `class Foo {}; class Foo`, + `class { + int x; + }`, `namespace a { namespace b { @@ -123,10 +133,12 @@ func TestNonBuiltinTypes() { expr := converter.ProcessType(typ) json := parse.MarshalASTExpr(expr) str := json.Print() + typstr := typ.String() - c.Printf(c.Str("Type: %s:\n"), typ.String()) + c.Printf(c.Str("Type: %s:\n"), typstr) c.Printf(c.Str("%s\n"), str) + typstr.Dispose() cjson.FreeCStr(str) json.Delete() index.Dispose()