llcppsigfetch:tag expr

This commit is contained in:
luoliwoshang
2024-08-22 15:57:21 +08:00
parent a4f850c0c6
commit eb4d721175
4 changed files with 196 additions and 13 deletions

View File

@@ -230,10 +230,16 @@ func (ct *Converter) Convert() (map[string]*ast.File, error) {
}
func (ct *Converter) ProcessType(t clang.Type) ast.Expr {
var expr ast.Expr
if t.Kind >= clang.TypeFirstBuiltin && t.Kind <= clang.TypeLastBuiltin {
return ct.ProcessBuiltinType(t)
}
if t.Kind == clang.TypeElaborated {
return ct.ProcessElaboratedType(t)
}
var expr ast.Expr
switch t.Kind {
case clang.TypePointer:
expr = &ast.PointerType{X: ct.ProcessType(t.PointeeType())}
@@ -268,21 +274,10 @@ func (ct *Converter) ProcessTypeDef(cursor clang.Cursor) *ast.TypedefDecl {
return &ast.TypedefDecl{
DeclBase: ct.CreateDeclBase(cursor),
Name: &ast.Ident{Name: c.GoString(name.CStr())},
Type: ct.ProcessUnderLyingType(cursor),
Type: ct.ProcessType(cursor.TypedefDeclUnderlyingType()),
}
}
func (ct *Converter) ProcessUnderLyingType(cursor clang.Cursor) ast.Expr {
underlying := cursor.TypedefDeclUnderlyingType()
// enum,union,class,struct,typedef -> elaborated type
if underlying.Kind == clang.TypeElaborated {
return &ast.Ident{
Name: c.GoString(underlying.String().CStr()),
}
}
return ct.ProcessType(underlying)
}
func (ct *Converter) ProcessFunc(cursor clang.Cursor) *ast.FuncDecl {
name := cursor.String()
defer name.Dispose()
@@ -487,6 +482,36 @@ func (ct *Converter) ProcessClass(cursor clang.Cursor) *ast.TypeDecl {
return ct.ProcessRecord(cursor, ast.Class)
}
func (ct *Converter) ProcessElaboratedType(t clang.Type) ast.Expr {
name := t.String()
defer name.Dispose()
typeName := c.GoString(name.CStr())
tagMap := map[string]ast.Tag{
"struct": ast.Struct,
"union": ast.Union,
"enum": ast.Enum,
"class": ast.Class,
}
// for elaborated type, it could have a tag description
// like struct A, union B, class C, enum D
parts := strings.SplitN(typeName, " ", 2)
if len(parts) == 2 {
if tagValue, ok := tagMap[parts[0]]; ok {
return &ast.TagExpr{
Tag: tagValue,
Name: &ast.Ident{Name: parts[1]},
}
}
}
return &ast.Ident{
Name: typeName,
}
}
func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType {
kind := ast.Void
var flags ast.TypeFlag

View File

@@ -194,6 +194,151 @@ TestTypeDefDecl Case 3:
}
}
TestTypeDefDecl Case 4:
{
"temp.h": {
"decls": [{
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "StructFoo"
},
"Type": {
"Tag": 0,
"Fields": {
"List": []
},
"Methods": []
}
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "UnionFoo"
},
"Type": {
"Tag": 1,
"Fields": {
"List": []
},
"Methods": []
}
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "ClassFoo"
},
"Name": {
"Name": "ClassFoo"
},
"Type": {
"Tag": 3,
"Fields": {
"List": []
},
"Methods": []
}
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "EnumFoo"
},
"Items": []
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "STRUCT_FOO"
},
"Type": {
"Name": {
"Name": "StructFoo"
},
"Tag": 0
}
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "UNION_FOO"
},
"Type": {
"Name": {
"Name": "UnionFoo"
},
"Tag": 1
}
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "CLASS_FOO"
},
"Type": {
"Name": {
"Name": "ClassFoo"
},
"Tag": 3
}
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "ENUM_FOO"
},
"Type": {
"Name": {
"Name": "EnumFoo"
},
"Tag": 2
}
}],
"includes": [],
"macros": []
}
}
#stderr

View File

@@ -10,6 +10,7 @@ func TestTypeDefDecl() {
testCases := []string{
`typedef int INT;`,
`typedef int INT;
typedef INT STANDARD_INT;`,
`struct StructFoo {};
union UnionFoo {};
@@ -19,6 +20,15 @@ func TestTypeDefDecl() {
typedef UnionFoo UNION_FOO;
typedef ClassFoo CLASS_FOO;
typedef EnumFoo ENUM_FOO;`,
`struct StructFoo {};
union UnionFoo {};
class ClassFoo {};
enum EnumFoo {};
typedef struct StructFoo STRUCT_FOO;
typedef union UnionFoo UNION_FOO;
typedef class ClassFoo CLASS_FOO;
typedef enum EnumFoo ENUM_FOO;`,
}
test.RunTest("TestTypeDefDecl", testCases)
}

View File

@@ -140,6 +140,9 @@ func MarshalASTExpr(t ast.Expr) *cjson.JSON {
return cjson.Null()
}
root.SetItem(c.Str("Name"), cjson.String(c.AllocaCStr(d.Name)))
case *ast.TagExpr:
root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name))
root.SetItem(c.Str("Tag"), cjson.Number(float64(d.Tag)))
case *ast.EnumItem:
root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name))
root.SetItem(c.Str("Value"), MarshalASTExpr(d.Value))