diff --git a/chore/_xtool/llcppsigfetch/parse/cvt.go b/chore/_xtool/llcppsigfetch/parse/cvt.go index ff93aa0f..4340dd4e 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt.go @@ -488,10 +488,15 @@ func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType { flags |= ast.Long | ast.Double case clang.TypeFloat128: kind = ast.Float128 - case clang.TypeComplex: // double | float + case clang.TypeComplex: kind = ast.Complex complexKind := t.ElementType().Kind - println("complex kind:", complexKind) // in unit test, will panic + if complexKind == clang.TypeLongDouble { + flags |= ast.Long | ast.Double + } else if complexKind == clang.TypeDouble { + flags |= ast.Double + } + // float complfex flag is not set default: // like IBM128,NullPtr,Accum kindStr := t.Kind.String() 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 9d5fac9c..4ef2b3c1 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/llgo.expect +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/llgo.expect @@ -22,6 +22,9 @@ Float16:flags:0 kind:9 Double:flags:16 kind:8 LongDouble:flags:20 kind:8 Float128:flags:0 kind:10 +Complex:flags:0 kind:11 +Complex:flags:16 kind:11 +Complex:flags:20 kind:11 Unknown:flags:0 kind:0 #stderr 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 e414e985..c7260d10 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/type.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/type.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "unsafe" "github.com/goplus/llgo/c/clang" "github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse" @@ -14,7 +15,7 @@ func main() { func TestBuiltinType() { tests := []struct { name string - typ *clang.Type + typ clang.Type expected ast.BuiltinType }{ {"Void", btType(clang.TypeVoid), ast.BuiltinType{Kind: ast.Void}}, @@ -40,13 +41,16 @@ func TestBuiltinType() { {"Double", btType(clang.TypeDouble), ast.BuiltinType{Kind: ast.Float, Flags: ast.Double}}, {"LongDouble", btType(clang.TypeLongDouble), ast.BuiltinType{Kind: ast.Float, Flags: ast.Long | ast.Double}}, {"Float128", btType(clang.TypeFloat128), ast.BuiltinType{Kind: ast.Float128}}, + {"Complex", mockComplexType(0), ast.BuiltinType{Kind: ast.Complex}}, + {"Complex", mockComplexType(ast.Double), ast.BuiltinType{Flags: ast.Double, Kind: ast.Complex}}, + {"Complex", mockComplexType(ast.Long | ast.Double), ast.BuiltinType{Flags: ast.Long | ast.Double, Kind: ast.Complex}}, {"Unknown", btType(clang.TypeIbm128), ast.BuiltinType{Kind: ast.Void}}, } converter := &parse.Converter{} converter.Convert() for _, bt := range tests { - res := converter.ProcessBuiltinType(*bt.typ) + res := converter.ProcessBuiltinType(bt.typ) if res.Kind != bt.expected.Kind { fmt.Printf("%s Kind mismatch:got %d want %d, \n", bt.name, res.Kind, bt.expected.Kind) } @@ -57,6 +61,44 @@ func TestBuiltinType() { } } -func btType(kind clang.TypeKind) *clang.Type { - return &clang.Type{Kind: kind} +func btType(kind clang.TypeKind) clang.Type { + return clang.Type{Kind: kind} +} + +func visit(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult { + typ := (*clang.Type)(clientData) + if cursor.Kind == clang.CursorVarDecl && cursor.Type().Kind == clang.TypeComplex { + *typ = cursor.Type() + } + return clang.ChildVisit_Continue +} + +// mock complex type, this type cannot be directly created in Go +func mockComplexType(flag ast.TypeFlag) clang.Type { + var typeStr string + if flag&(ast.Long|ast.Double) == (ast.Long | ast.Double) { + typeStr = "long double" + } else if flag&ast.Double != 0 { + typeStr = "double" + } else { + typeStr = "float" + } + + code := fmt.Sprintf("#include \n%s complex z;", typeStr) + index, unit, err := parse.CreateTranslationUnit(&parse.Config{ + File: code, + Temp: true, + Args: []string{"-x", "c", "-std=c99"}, + }) + if err != nil { + panic(err) + } + + defer index.Dispose() + + cursor := unit.Cursor() + complex := &clang.Type{} + clang.VisitChildren(cursor, visit, unsafe.Pointer(complex)) + + return *complex }