llcppsigfetch:anonymous elaborated type refer

This commit is contained in:
luoliwoshang
2024-08-27 18:50:51 +08:00
parent 0ac48369fe
commit 9351a1f900
7 changed files with 346 additions and 14 deletions

View File

@@ -372,22 +372,26 @@ func visitEnum(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.Chi
return clang.ChildVisit_Continue return clang.ChildVisit_Continue
} }
func (ct *Converter) ProcessEnumDecl(cursor clang.Cursor) *ast.EnumTypeDecl { func (ct *Converter) ProcessEnumType(cursor clang.Cursor) *ast.EnumType {
name := cursor.String()
defer name.Dispose()
items := make([]*ast.EnumItem, 0) items := make([]*ast.EnumItem, 0)
ctx := &visitEnumContext{ ctx := &visitEnumContext{
enum: &items, enum: &items,
converter: ct, converter: ct,
} }
clang.VisitChildren(cursor, visitEnum, c.Pointer(ctx)) 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{ return &ast.EnumTypeDecl{
DeclBase: ct.CreateDeclBase(cursor), DeclBase: ct.CreateDeclBase(cursor),
Name: &ast.Ident{Name: c.GoString(name.CStr())}, Name: &ast.Ident{Name: c.GoString(name.CStr())},
Type: &ast.EnumType{ Type: ct.ProcessEnumType(cursor),
Items: items,
},
} }
} }
@@ -501,7 +505,7 @@ func (ct *Converter) ProcessMethods(cursor clang.Cursor) []*ast.FuncDecl {
return methods 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() anony := cursor.IsAnonymousRecordDecl()
var name *ast.Ident var name *ast.Ident
@@ -514,23 +518,23 @@ func (ct *Converter) ProcessRecordDecl(cursor clang.Cursor, tag ast.Tag) *ast.Ty
return &ast.TypeDecl{ return &ast.TypeDecl{
DeclBase: ct.CreateDeclBase(cursor), DeclBase: ct.CreateDeclBase(cursor),
Name: name, Name: name,
Type: ct.ProcessRecordType(cursor, tag), Type: ct.ProcessRecordType(cursor),
} }
} }
func (ct *Converter) ProcessStructDecl(cursor clang.Cursor) *ast.TypeDecl { 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 { 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 { func (ct *Converter) ProcessClassDecl(cursor clang.Cursor) *ast.TypeDecl {
// Pushing class scope before processing its type and popping after // Pushing class scope before processing its type and popping after
base := ct.CreateDeclBase(cursor) base := ct.CreateDeclBase(cursor)
typ := ct.ProcessRecordType(cursor, ast.Class) typ := ct.ProcessRecordType(cursor)
return &ast.TypeDecl{ return &ast.TypeDecl{
DeclBase: base, 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{ return &ast.RecordType{
Tag: tag, Tag: tagMap[cursor.Kind],
Fields: ct.ProcessFieldList(cursor), Fields: ct.ProcessFieldList(cursor),
Methods: ct.ProcessMethods(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 { func (ct *Converter) ProcessElaboratedType(t clang.Type) ast.Expr {
name := t.String() name := t.String()
defer name.Dispose() 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()) typeName := c.GoString(name.CStr())
tagMap := map[string]ast.Tag{ tagMap := map[string]ast.Tag{

View File

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

View File

@@ -22,6 +22,14 @@ func TestStructDecl() {
int a; int a;
int (*Foo)(int, int); int (*Foo)(int, int);
};`, };`,
`struct Person {
int age;
struct {
int year;
int day;
int month;
} birthday;
};`,
} }
test.RunTest("TestStructDecl", testCases) test.RunTest("TestStructDecl", testCases)
} }

View File

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

View File

@@ -16,6 +16,14 @@ func TestUnionDecl() {
int a; int a;
int b; int b;
};`, };`,
`union OuterUnion {
int i;
float f;
union {
char c;
short s;
} inner;
};`,
} }
test.RunTest("TestUnionDecl", testCases) test.RunTest("TestUnionDecl", testCases)
} }

View File

@@ -105,6 +105,28 @@ Type: struct Foo:
}, },
"Tag": 0 "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: Type: Foo:
{ {
"Name": "Foo" "Name": "Foo"
@@ -116,6 +138,28 @@ Type: union Foo:
}, },
"Tag": 1 "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: Type: Foo:
{ {
"Name": "Foo" "Name": "Foo"
@@ -127,6 +171,18 @@ Type: enum Foo:
}, },
"Tag": 2 "Tag": 2
} }
Type: enum (unnamed enum at temp.h:1:1):
{
"Items": [{
"Name": {
"Name": "x"
},
"Value": {
"Kind": 0,
"Value": "42"
}
}]
}
Type: Foo: Type: Foo:
{ {
"Name": "Foo" "Name": "Foo"
@@ -138,6 +194,28 @@ Type: class Foo:
}, },
"Tag": 3 "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: Type: a::b::c:
{ {
"X": { "X": {

View File

@@ -80,21 +80,31 @@ func TestNonBuiltinTypes() {
Foo`, Foo`,
`struct Foo {}; `struct Foo {};
struct Foo`, struct Foo`,
`struct {
int x;
}`,
`union Foo {}; `union Foo {};
Foo`, Foo`,
`union Foo {}; `union Foo {};
union Foo`, union Foo`,
`union {
int x;
}`,
`enum Foo {}; `enum Foo {};
Foo`, Foo`,
`enum Foo {}; `enum Foo {};
enum Foo`, enum Foo`,
`enum { x = 42 }`,
`class Foo {}; `class Foo {};
Foo`, Foo`,
`class Foo {}; `class Foo {};
class Foo`, class Foo`,
`class {
int x;
}`,
`namespace a { `namespace a {
namespace b { namespace b {
@@ -123,10 +133,12 @@ func TestNonBuiltinTypes() {
expr := converter.ProcessType(typ) expr := converter.ProcessType(typ)
json := parse.MarshalASTExpr(expr) json := parse.MarshalASTExpr(expr)
str := json.Print() 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) c.Printf(c.Str("%s\n"), str)
typstr.Dispose()
cjson.FreeCStr(str) cjson.FreeCStr(str)
json.Delete() json.Delete()
index.Dispose() index.Dispose()