diff --git a/chore/_xtool/llcppsigfetch/parse/cvt.go b/chore/_xtool/llcppsigfetch/parse/cvt.go index 07d4efd4..ff93aa0f 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt.go @@ -22,40 +22,16 @@ type Converter struct { scopeStack []ast.Expr //namespace & class } -func NewConverter(file string, temp bool) (*Converter, error) { - args := []*c.Char{ - c.Str("-x"), - c.Str("c++"), - c.Str("-std=c++11"), - } - index := clang.CreateIndex(0, 0) +type Config struct { + File string + Temp bool + Args []string +} - var unit *clang.TranslationUnit - - if temp { - content := c.AllocaCStr(file) - tempFile := &clang.UnsavedFile{ - Filename: c.Str("temp.h"), - Contents: content, - Length: c.Ulong(c.Strlen(content)), - } - unit = index.ParseTranslationUnit( - tempFile.Filename, - unsafe.SliceData(args), c.Int(len(args)), - tempFile, 1, - clang.DetailedPreprocessingRecord, - ) - } else { - unit = index.ParseTranslationUnit( - c.AllocaCStr(file), - unsafe.SliceData(args), c.Int(len(args)), - nil, 0, - clang.DetailedPreprocessingRecord, - ) - } - - if unit == nil { - return nil, errors.New("failed to parse translation unit") +func NewConverter(config *Config) (*Converter, error) { + index, unit, err := CreateTranslationUnit(config) + if err != nil { + return nil, err } return &Converter{ @@ -65,6 +41,52 @@ func NewConverter(file string, temp bool) (*Converter, error) { }, nil } +func CreateTranslationUnit(config *Config) (*clang.Index, *clang.TranslationUnit, error) { + if config.Args == nil { + config.Args = []string{"-x", "c++", "-std=c++11"} + } + + cArgs := make([]*c.Char, len(config.Args)) + for i, arg := range config.Args { + cArgs[i] = c.AllocaCStr(arg) + } + + index := clang.CreateIndex(0, 0) + + var unit *clang.TranslationUnit + + if config.Temp { + content := c.AllocaCStr(config.File) + tempFile := &clang.UnsavedFile{ + Filename: c.Str("temp.h"), + Contents: content, + Length: c.Ulong(c.Strlen(content)), + } + + unit = index.ParseTranslationUnit( + tempFile.Filename, + unsafe.SliceData(cArgs), c.Int(len(cArgs)), + tempFile, 1, + clang.DetailedPreprocessingRecord, + ) + + } else { + cFile := c.AllocaCStr(config.File) + unit = index.ParseTranslationUnit( + cFile, + unsafe.SliceData(cArgs), c.Int(len(cArgs)), + nil, 0, + clang.DetailedPreprocessingRecord, + ) + } + + if unit == nil { + return nil, nil, errors.New("failed to parse translation unit") + } + + return index, unit, nil +} + func (ct *Converter) Dispose() { ct.index.Dispose() ct.unit.Dispose() @@ -281,6 +303,7 @@ func (ct *Converter) ProcessEnum(cursor clang.Cursor) { Name: &ast.Ident{Name: c.GoString(name.CStr())}, Items: items, } + ct.curFile.Decls = append(ct.curFile.Decls, enum) } @@ -465,6 +488,10 @@ 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 + kind = ast.Complex + complexKind := t.ElementType().Kind + println("complex kind:", complexKind) // in unit test, will panic default: // like IBM128,NullPtr,Accum kindStr := t.Kind.String() diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go index e9b9a73e..bf60ef25 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go @@ -29,7 +29,10 @@ func TestFuncDecl() { } for i, content := range testCases { - converter, err := parse.NewConverter(content, true) + converter, err := parse.NewConverter(&parse.Config{ + File: content, + Temp: true, + }) if err != nil { panic(err) } @@ -68,7 +71,10 @@ func TestScope() { } for i, content := range testCases { - converter, err := parse.NewConverter(content, true) + converter, err := parse.NewConverter(&parse.Config{ + File: content, + Temp: true, + }) if err != nil { panic(err) } @@ -114,7 +120,10 @@ void foo();`, } for i, content := range testCases { - converter, err := parse.NewConverter(content, true) + converter, err := parse.NewConverter(&parse.Config{ + File: content, + Temp: true, + }) if err != nil { panic(err) } @@ -148,7 +157,10 @@ func TestStructDecl() { } for i, content := range testCases { - converter, err := parse.NewConverter(content, true) + converter, err := parse.NewConverter(&parse.Config{ + File: content, + Temp: true, + }) if err != nil { panic(err) } @@ -179,7 +191,10 @@ func TestClassDecl() { } for i, content := range testCases { - converter, err := parse.NewConverter(content, true) + converter, err := parse.NewConverter(&parse.Config{ + File: content, + Temp: true, + }) if err != nil { panic(err) } @@ -216,7 +231,10 @@ func TestEnumDecl() { } for i, content := range testCases { - converter, err := parse.NewConverter(content, true) + converter, err := parse.NewConverter(&parse.Config{ + File: content, + Temp: true, + }) if err != nil { panic(err) } diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/preprocess_test/preprocess.go b/chore/_xtool/llcppsigfetch/parse/cvt_test/preprocess_test/preprocess.go index f5ef45a5..e7d32afd 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/preprocess_test/preprocess.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/preprocess_test/preprocess.go @@ -17,7 +17,10 @@ func TestDefine() { } for i, content := range testCases { - converter, err := parse.NewConverter(content, true) + converter, err := parse.NewConverter(&parse.Config{ + File: content, + Temp: true, + }) if err != nil { panic(err) } @@ -41,7 +44,10 @@ func TestInclude() { } for i, content := range testCases { - converter, err := parse.NewConverter(content, true) + converter, err := parse.NewConverter(&parse.Config{ + File: content, + Temp: true, + }) if err != nil { panic(err) } 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 29d985cb..e414e985 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/type.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/type_test/type.go @@ -14,39 +14,39 @@ func main() { func TestBuiltinType() { tests := []struct { name string - typeKind clang.TypeKind + typ *clang.Type expected ast.BuiltinType }{ - {"Void", clang.TypeVoid, ast.BuiltinType{Kind: ast.Void}}, - {"Bool", clang.TypeBool, ast.BuiltinType{Kind: ast.Bool}}, - {"Char_S", clang.TypeCharS, ast.BuiltinType{Kind: ast.Char, Flags: ast.Signed}}, - {"Char_U", clang.TypeCharU, ast.BuiltinType{Kind: ast.Char, Flags: ast.Unsigned}}, - {"Char16", clang.TypeChar16, ast.BuiltinType{Kind: ast.Char16}}, - {"Char32", clang.TypeChar32, ast.BuiltinType{Kind: ast.Char32}}, - {"WChar", clang.TypeWChar, ast.BuiltinType{Kind: ast.WChar}}, - {"Short", clang.TypeShort, ast.BuiltinType{Kind: ast.Int, Flags: ast.Short}}, - {"UShort", clang.TypeUShort, ast.BuiltinType{Kind: ast.Int, Flags: ast.Short | ast.Unsigned}}, - {"Int", clang.TypeInt, ast.BuiltinType{Kind: ast.Int}}, - {"UInt", clang.TypeUInt, ast.BuiltinType{Kind: ast.Int, Flags: ast.Unsigned}}, - {"Long", clang.TypeLong, ast.BuiltinType{Kind: ast.Int, Flags: ast.Long}}, - {"ULong", clang.TypeULong, ast.BuiltinType{Kind: ast.Int, Flags: ast.Long | ast.Unsigned}}, - {"LongLong", clang.TypeLongLong, ast.BuiltinType{Kind: ast.Int, Flags: ast.LongLong}}, - {"ULongLong", clang.TypeULongLong, ast.BuiltinType{Kind: ast.Int, Flags: ast.LongLong | ast.Unsigned}}, - {"Int128", clang.TypeInt128, ast.BuiltinType{Kind: ast.Int128}}, - {"UInt128", clang.TypeUInt128, ast.BuiltinType{Kind: ast.Int128, Flags: ast.Unsigned}}, - {"Float", clang.TypeFloat, ast.BuiltinType{Kind: ast.Float}}, - {"Half", clang.TypeHalf, ast.BuiltinType{Kind: ast.Float16}}, - {"Float16", clang.TypeFloat16, ast.BuiltinType{Kind: ast.Float16}}, - {"Double", clang.TypeDouble, ast.BuiltinType{Kind: ast.Float, Flags: ast.Double}}, - {"LongDouble", clang.TypeLongDouble, ast.BuiltinType{Kind: ast.Float, Flags: ast.Long | ast.Double}}, - {"Float128", clang.TypeFloat128, ast.BuiltinType{Kind: ast.Float128}}, - {"Unknown", clang.TypeIbm128, ast.BuiltinType{Kind: ast.Void}}, + {"Void", btType(clang.TypeVoid), ast.BuiltinType{Kind: ast.Void}}, + {"Bool", btType(clang.TypeBool), ast.BuiltinType{Kind: ast.Bool}}, + {"Char_S", btType(clang.TypeCharS), ast.BuiltinType{Kind: ast.Char, Flags: ast.Signed}}, + {"Char_U", btType(clang.TypeCharU), ast.BuiltinType{Kind: ast.Char, Flags: ast.Unsigned}}, + {"Char16", btType(clang.TypeChar16), ast.BuiltinType{Kind: ast.Char16}}, + {"Char32", btType(clang.TypeChar32), ast.BuiltinType{Kind: ast.Char32}}, + {"WChar", btType(clang.TypeWChar), ast.BuiltinType{Kind: ast.WChar}}, + {"Short", btType(clang.TypeShort), ast.BuiltinType{Kind: ast.Int, Flags: ast.Short}}, + {"UShort", btType(clang.TypeUShort), ast.BuiltinType{Kind: ast.Int, Flags: ast.Short | ast.Unsigned}}, + {"Int", btType(clang.TypeInt), ast.BuiltinType{Kind: ast.Int}}, + {"UInt", btType(clang.TypeUInt), ast.BuiltinType{Kind: ast.Int, Flags: ast.Unsigned}}, + {"Long", btType(clang.TypeLong), ast.BuiltinType{Kind: ast.Int, Flags: ast.Long}}, + {"ULong", btType(clang.TypeULong), ast.BuiltinType{Kind: ast.Int, Flags: ast.Long | ast.Unsigned}}, + {"LongLong", btType(clang.TypeLongLong), ast.BuiltinType{Kind: ast.Int, Flags: ast.LongLong}}, + {"ULongLong", btType(clang.TypeULongLong), ast.BuiltinType{Kind: ast.Int, Flags: ast.LongLong | ast.Unsigned}}, + {"Int128", btType(clang.TypeInt128), ast.BuiltinType{Kind: ast.Int128}}, + {"UInt128", btType(clang.TypeUInt128), ast.BuiltinType{Kind: ast.Int128, Flags: ast.Unsigned}}, + {"Float", btType(clang.TypeFloat), ast.BuiltinType{Kind: ast.Float}}, + {"Half", btType(clang.TypeHalf), ast.BuiltinType{Kind: ast.Float16}}, + {"Float16", btType(clang.TypeFloat16), ast.BuiltinType{Kind: ast.Float16}}, + {"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}}, + {"Unknown", btType(clang.TypeIbm128), ast.BuiltinType{Kind: ast.Void}}, } + converter := &parse.Converter{} converter.Convert() for _, bt := range tests { - t := clang.Type{Kind: bt.typeKind} - res := converter.ProcessBuiltinType(t) + 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) } @@ -56,3 +56,7 @@ func TestBuiltinType() { fmt.Printf("%s:flags:%d kind:%d\n", bt.name, res.Flags, res.Kind) } } + +func btType(kind clang.TypeKind) *clang.Type { + return &clang.Type{Kind: kind} +} diff --git a/chore/_xtool/llcppsigfetch/parse/parse.go b/chore/_xtool/llcppsigfetch/parse/parse.go index e7b3bee4..ee42da75 100644 --- a/chore/_xtool/llcppsigfetch/parse/parse.go +++ b/chore/_xtool/llcppsigfetch/parse/parse.go @@ -59,7 +59,10 @@ func (p *Context) processFile(path string) error { } func (p *Context) parseFile(path string) (map[string]*ast.File, error) { - converter, err := NewConverter(path, false) + converter, err := NewConverter(&Config{ + File: path, + Temp: false, + }) if err != nil { return nil, errors.New("failed to create converter " + path) }