Merge pull request #803 from luoliwoshang/llcppsigfetch/output

llcppsigfetch:refine
This commit is contained in:
xushiwei
2024-09-24 19:08:53 +08:00
committed by GitHub
5 changed files with 132 additions and 175 deletions

View File

@@ -27,34 +27,42 @@ import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/cjson" "github.com/goplus/llgo/c/cjson"
"github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse" "github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse"
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
"github.com/goplus/llgo/chore/_xtool/llcppsymg/config" "github.com/goplus/llgo/chore/_xtool/llcppsymg/config"
) )
func main() { func main() {
if len(os.Args) == 1 { cfgFile := ""
// run with default config file outputToFile := false
runFromConfig() for i := 1; i < len(os.Args); i++ {
return arg := os.Args[i]
} if arg == "--extract" {
runExtract()
if os.Args[1] == "--extract" { return
runExtract() } else if arg == "--help" || arg == "-h" {
} else if os.Args[1] == "--help" || os.Args[1] == "-h" { printUsage()
printUsage() return
} else { } else if strings.HasPrefix(arg, "-out=") {
runFromConfig() outputToFile = parseBoolArg(arg, "out", false)
} else if cfgFile == "" && !strings.HasPrefix(arg, "-") {
cfgFile = arg
}
} }
runFromConfig(cfgFile, outputToFile)
} }
func printUsage() { func printUsage() {
fmt.Println("Usage:") fmt.Println("Usage:")
fmt.Println(" llcppsigfetch [<config_file>]") fmt.Println(" llcppsigfetch [<config_file>] [-out=<bool>]")
fmt.Println(" OR") fmt.Println(" OR")
fmt.Println(" llcppsigfetch --extract <file> <temp> [args...]") fmt.Println(" llcppsigfetch --extract <file> [-out=<bool>] [-temp=<bool>] [-cpp=<bool>] [args...]")
fmt.Println("") fmt.Println("")
fmt.Println("Options:") fmt.Println("Options:")
fmt.Println(" [<config_file>]: Path to the configuration file (use '-' for stdin)") fmt.Println(" [<config_file>]: Path to the configuration file (use '-' for stdin)")
fmt.Println(" If not provided, uses default 'llcppg.cfg'") fmt.Println(" If not provided, uses default 'llcppg.cfg'")
fmt.Println(" -out=<bool>: Optional. Set to 'true' to output results to a file,")
fmt.Println(" 'false' (default) to output to stdout")
fmt.Println(" This option can be used with both modes")
fmt.Println("") fmt.Println("")
fmt.Println(" --extract: Extract information from a single file") fmt.Println(" --extract: Extract information from a single file")
fmt.Println(" <file>: Path to the file to process, or file content if -temp=true") fmt.Println(" <file>: Path to the file to process, or file content if -temp=true")
@@ -71,10 +79,9 @@ func printUsage() {
fmt.Println("Note: The two usage modes are mutually exclusive. Use either [<config_file>] OR --extract, not both.") fmt.Println("Note: The two usage modes are mutually exclusive. Use either [<config_file>] OR --extract, not both.")
} }
func runFromConfig() { func runFromConfig(cfgFile string, outputToFile bool) {
cfgFile := "llcppg.cfg" if cfgFile == "" {
if len(os.Args) > 1 { cfgFile = "llcppg.cfg"
cfgFile = os.Args[1]
} }
var data []byte var data []byte
@@ -100,7 +107,7 @@ func runFromConfig() {
err = context.ProcessFiles(files) err = context.ProcessFiles(files)
check(err) check(err)
outputInfo(context) outputInfo(context, outputToFile)
} }
func runExtract() { func runExtract() {
@@ -110,13 +117,14 @@ func runExtract() {
os.Exit(1) os.Exit(1)
} }
cfg := &parse.Config{ cfg := &clangutils.Config{
File: os.Args[2], File: os.Args[2],
Args: []string{}, Args: []string{},
IsCpp: true, IsCpp: true,
Temp: false, Temp: false,
} }
outputToFile := false
for i := 3; i < len(os.Args); i++ { for i := 3; i < len(os.Args); i++ {
arg := os.Args[i] arg := os.Args[i]
switch { switch {
@@ -128,6 +136,10 @@ func runExtract() {
cfg.IsCpp = parseBoolArg(arg, "cpp", true) cfg.IsCpp = parseBoolArg(arg, "cpp", true)
os.Args = append(os.Args[:i], os.Args[i+1:]...) os.Args = append(os.Args[:i], os.Args[i+1:]...)
i-- i--
case strings.HasPrefix(arg, "-out="):
outputToFile = parseBoolArg(arg, "out", false)
os.Args = append(os.Args[:i], os.Args[i+1:]...)
i--
default: default:
cfg.Args = append(cfg.Args, arg) cfg.Args = append(cfg.Args, arg)
} }
@@ -139,7 +151,7 @@ func runExtract() {
check(err) check(err)
result := converter.MarshalOutputASTFiles() result := converter.MarshalOutputASTFiles()
cstr := result.Print() cstr := result.Print()
c.Printf(cstr) outputResult(cstr, outputToFile)
cjson.FreeCStr(cstr) cjson.FreeCStr(cstr)
result.Delete() result.Delete()
converter.Dispose() converter.Dispose()
@@ -151,6 +163,20 @@ func check(err error) {
} }
} }
func outputResult(result *c.Char, outputToFile bool) {
if outputToFile {
outputFile := "llcppg.sigfetch.json"
err := os.WriteFile(outputFile, []byte(c.GoString(result)), 0644)
if err != nil {
fmt.Fprintf(os.Stderr, "Error writing to output file: %v\n", err)
os.Exit(1)
}
fmt.Printf("Results saved to %s\n", outputFile)
} else {
c.Printf(result)
}
}
func getHeaderFiles(cflags string, files []string) []string { func getHeaderFiles(cflags string, files []string) []string {
prefix := cflags prefix := cflags
prefix = strings.TrimPrefix(prefix, "-I") prefix = strings.TrimPrefix(prefix, "-I")
@@ -161,12 +187,12 @@ func getHeaderFiles(cflags string, files []string) []string {
return paths return paths
} }
func outputInfo(context *parse.Context) { func outputInfo(context *parse.Context, outputToFile bool) {
info := context.Output() info := context.Output()
str := info.Print() str := info.Print()
defer cjson.FreeCStr(str) defer cjson.FreeCStr(str)
defer info.Delete() defer info.Delete()
c.Printf(str) outputResult(str, outputToFile)
} }
func parseBoolArg(arg, name string, defaultValue bool) bool { func parseBoolArg(arg, name string, defaultValue bool) bool {

View File

@@ -1,7 +1,6 @@
package parse package parse
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"strings" "strings"
@@ -10,6 +9,7 @@ import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/cjson" "github.com/goplus/llgo/c/cjson"
"github.com/goplus/llgo/c/clang" "github.com/goplus/llgo/c/clang"
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
"github.com/goplus/llgo/chore/llcppg/ast" "github.com/goplus/llgo/chore/llcppg/ast"
"github.com/goplus/llgo/chore/llcppg/token" "github.com/goplus/llgo/chore/llcppg/token"
) )
@@ -63,8 +63,8 @@ type Config struct {
IsCpp bool IsCpp bool
} }
func NewConverter(config *Config) (*Converter, error) { func NewConverter(config *clangutils.Config) (*Converter, error) {
index, unit, err := CreateTranslationUnit(config) index, unit, err := clangutils.CreateTranslationUnit(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -78,56 +78,6 @@ func NewConverter(config *Config) (*Converter, error) {
}, nil }, nil
} }
func CreateTranslationUnit(config *Config) (*clang.Index, *clang.TranslationUnit, error) {
// default use the c/c++ standard of clang; c:gnu17 c++:gnu++17
// https://clang.llvm.org/docs/CommandGuide/clang.html
defaultArgs := []string{"-x", "c"}
if config.IsCpp {
defaultArgs = []string{"-x", "c++"}
}
allArgs := append(defaultArgs, config.Args...)
cArgs := make([]*c.Char, len(allArgs))
for i, arg := range allArgs {
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() { func (ct *Converter) Dispose() {
ct.index.Dispose() ct.index.Dispose()
ct.unit.Dispose() ct.unit.Dispose()
@@ -259,14 +209,13 @@ func (ct *Converter) ParseComment(rawComment string) *ast.CommentGroup {
lines := strings.Split(rawComment, "\n") lines := strings.Split(rawComment, "\n")
commentGroup := &ast.CommentGroup{} commentGroup := &ast.CommentGroup{}
for _, line := range lines { for _, line := range lines {
commentGroup.List = append(commentGroup.List, &ast.Comment{Text: line}) commentGroup.List = append(commentGroup.List, &ast.Comment{Text: line + "\n"})
} }
return commentGroup return commentGroup
} }
// visit top decls (struct,class,function,enum & macro,include) // visit top decls (struct,class,function,enum & macro,include)
func visitTop(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult { func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResult {
ct := (*Converter)(clientData)
ct.UpdateLoc(cursor) ct.UpdateLoc(cursor)
curFile := ct.GetCurFile() curFile := ct.GetCurFile()
@@ -300,7 +249,7 @@ func visitTop(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.Chil
case clang.CursorTypedefDecl: case clang.CursorTypedefDecl:
curFile.Decls = append(curFile.Decls, ct.ProcessTypeDefDecl(cursor)) curFile.Decls = append(curFile.Decls, ct.ProcessTypeDefDecl(cursor))
case clang.CursorNamespace: case clang.CursorNamespace:
clang.VisitChildren(cursor, visitTop, c.Pointer(ct)) VisitChildren(cursor, ct.visitTop)
} }
return clang.ChildVisit_Continue return clang.ChildVisit_Continue
} }
@@ -308,10 +257,19 @@ func visitTop(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.Chil
func (ct *Converter) Convert() ([]*FileEntry, error) { func (ct *Converter) Convert() ([]*FileEntry, error) {
cursor := ct.unit.Cursor() cursor := ct.unit.Cursor()
// visit top decls (struct,class,function & macro,include) // visit top decls (struct,class,function & macro,include)
clang.VisitChildren(cursor, visitTop, c.Pointer(ct)) VisitChildren(cursor, ct.visitTop)
return ct.Files, nil return ct.Files, nil
} }
type Visitor func(cursor, parent clang.Cursor) clang.ChildVisitResult
func VisitChildren(cursor clang.Cursor, fn Visitor) c.Uint {
return clang.VisitChildren(cursor, func(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
cfn := *(*Visitor)(clientData)
return cfn(cursor, parent)
}, unsafe.Pointer(&fn))
}
func (ct *Converter) ProcessType(t clang.Type) ast.Expr { func (ct *Converter) ProcessType(t clang.Type) ast.Expr {
if t.Kind >= clang.TypeFirstBuiltin && t.Kind <= clang.TypeLastBuiltin { if t.Kind >= clang.TypeFirstBuiltin && t.Kind <= clang.TypeLastBuiltin {
return ct.ProcessBuiltinType(t) return ct.ProcessBuiltinType(t)
@@ -519,38 +477,30 @@ func (ct *Converter) ProcessMethodAttributes(cursor clang.Cursor, fn *ast.FuncDe
overridden.DisposeOverriddenCursors() overridden.DisposeOverriddenCursors()
} }
type visitEnumContext struct {
enum *[]*ast.EnumItem
converter *Converter
}
func visitEnum(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
ctx := (*visitEnumContext)(clientData)
if cursor.Kind == clang.CursorEnumConstantDecl {
name := cursor.String()
val := (*c.Char)(c.Malloc(unsafe.Sizeof(c.Char(0)) * 20))
c.Sprintf(val, c.Str("%lld"), cursor.EnumConstantDeclValue())
defer c.Free(unsafe.Pointer(val))
defer name.Dispose()
enum := &ast.EnumItem{
Name: &ast.Ident{Name: c.GoString(name.CStr())},
Value: &ast.BasicLit{
Kind: ast.IntLit,
Value: c.GoString(val),
},
}
*ctx.enum = append(*ctx.enum, enum)
}
return clang.ChildVisit_Continue
}
func (ct *Converter) ProcessEnumType(cursor clang.Cursor) *ast.EnumType { func (ct *Converter) ProcessEnumType(cursor clang.Cursor) *ast.EnumType {
items := make([]*ast.EnumItem, 0) items := make([]*ast.EnumItem, 0)
ctx := &visitEnumContext{
enum: &items, VisitChildren(cursor, func(cursor, parent clang.Cursor) clang.ChildVisitResult {
converter: ct, if cursor.Kind == clang.CursorEnumConstantDecl {
} name := cursor.String()
clang.VisitChildren(cursor, visitEnum, c.Pointer(ctx)) defer name.Dispose()
val := (*c.Char)(c.Malloc(unsafe.Sizeof(c.Char(0)) * 20))
c.Sprintf(val, c.Str("%lld"), cursor.EnumConstantDeclValue())
defer c.Free(unsafe.Pointer(val))
enum := &ast.EnumItem{
Name: &ast.Ident{Name: c.GoString(name.CStr())},
Value: &ast.BasicLit{
Kind: ast.IntLit,
Value: c.GoString(val),
},
}
items = append(items, enum)
}
return clang.ChildVisit_Continue
})
return &ast.EnumType{ return &ast.EnumType{
Items: items, Items: items,
} }
@@ -587,6 +537,8 @@ func (ct *Converter) ProcessInclude(cursor clang.Cursor) *ast.Include {
return &ast.Include{Path: c.GoString(name.CStr())} return &ast.Include{Path: c.GoString(name.CStr())}
} }
// todo(zzy): after https://github.com/goplus/llgo/issues/804 has be resolved
// Change the following code to use the closure
type visitFieldContext struct { type visitFieldContext struct {
params *ast.FieldList params *ast.FieldList
converter *Converter converter *Converter
@@ -851,23 +803,10 @@ func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType {
// Constructs a complete scoping expression by traversing the semantic parents, starting from the given clang.Cursor // Constructs a complete scoping expression by traversing the semantic parents, starting from the given clang.Cursor
// For anonymous decl of typedef references, use their anonymous name // For anonymous decl of typedef references, use their anonymous name
func (ct *Converter) BuildScopingExpr(cursor clang.Cursor) ast.Expr { func (ct *Converter) BuildScopingExpr(cursor clang.Cursor) ast.Expr {
parts := ct.BuildScopingParts(cursor) parts := clangutils.BuildScopingParts(cursor)
return buildScopingFromParts(parts) return buildScopingFromParts(parts)
} }
func (ct *Converter) BuildScopingParts(cursor clang.Cursor) []string {
var parts []string
// Traverse up the semantic parents
for cursor.IsNull() != 1 && cursor.Kind != clang.CursorTranslationUnit {
name := cursor.String()
qualified := c.GoString(name.CStr())
parts = append([]string{qualified}, parts...)
cursor = cursor.SemanticParent()
name.Dispose()
}
return parts
}
func (ct *Converter) MarshalASTFiles() *cjson.JSON { func (ct *Converter) MarshalASTFiles() *cjson.JSON {
return MarshalASTFiles(ct.Files) return MarshalASTFiles(ct.Files)
} }

View File

@@ -2,17 +2,17 @@ package cvttest
import ( import (
"fmt" "fmt"
"unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/cjson" "github.com/goplus/llgo/c/cjson"
"github.com/goplus/llgo/c/clang" "github.com/goplus/llgo/c/clang"
"github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse" "github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse"
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
) )
func RunTest(testName string, testCases []string) { func RunTest(testName string, testCases []string) {
for i, content := range testCases { for i, content := range testCases {
converter, err := parse.NewConverter(&parse.Config{ converter, err := parse.NewConverter(&clangutils.Config{
File: content, File: content,
Temp: true, Temp: true,
IsCpp: true, IsCpp: true,
@@ -63,7 +63,7 @@ type GetTypeOptions struct {
// e.g. index.Dispose(), unit.Dispose() // e.g. index.Dispose(), unit.Dispose()
func GetType(option *GetTypeOptions) (clang.Type, *clang.Index, *clang.TranslationUnit) { func GetType(option *GetTypeOptions) (clang.Type, *clang.Index, *clang.TranslationUnit) {
code := fmt.Sprintf("%s placeholder;", option.TypeCode) code := fmt.Sprintf("%s placeholder;", option.TypeCode)
index, unit, err := parse.CreateTranslationUnit(&parse.Config{ index, unit, err := clangutils.CreateTranslationUnit(&clangutils.Config{
File: code, File: code,
Temp: true, Temp: true,
Args: option.Args, Args: option.Args,
@@ -73,22 +73,13 @@ func GetType(option *GetTypeOptions) (clang.Type, *clang.Index, *clang.Translati
panic(err) panic(err)
} }
cursor := unit.Cursor() cursor := unit.Cursor()
visitType := &typeVisitData{typ: &clang.Type{}, expectTypeKind: option.ExpectTypeKind} var typ clang.Type
parse.VisitChildren(cursor, func(child, parent clang.Cursor) clang.ChildVisitResult {
clang.VisitChildren(cursor, typeVisit, unsafe.Pointer(visitType)) if child.Kind == clang.CursorVarDecl && (option.ExpectTypeKind == clang.TypeInvalid || option.ExpectTypeKind == child.Type().Kind) {
return *visitType.typ, index, unit typ = child.Type()
} return clang.ChildVisit_Break
}
type typeVisitData struct { return clang.ChildVisit_Continue
typ *clang.Type })
expectTypeKind clang.TypeKind return typ, index, unit
}
func typeVisit(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
visitData := (*typeVisitData)(clientData)
if cursor.Kind == clang.CursorVarDecl && (visitData.expectTypeKind == clang.TypeInvalid || cursor.Type().Kind == visitData.expectTypeKind) {
*visitData.typ = cursor.Type()
return clang.ChildVisit_Break
}
return clang.ChildVisit_Continue
} }

View File

@@ -99,7 +99,7 @@ TestDoc Case 3:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/// doc" "Text": "/// doc\n"
}] }]
}, },
"Parent": null, "Parent": null,
@@ -148,7 +148,7 @@ TestDoc Case 4:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/** doc */" "Text": "/** doc */\n"
}] }]
}, },
"Parent": null, "Parent": null,
@@ -197,7 +197,7 @@ TestDoc Case 5:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/*! doc */" "Text": "/*! doc */\n"
}] }]
}, },
"Parent": null, "Parent": null,
@@ -246,10 +246,10 @@ TestDoc Case 6:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/// doc 1" "Text": "/// doc 1\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": "/// doc 2" "Text": "/// doc 2\n"
}] }]
}, },
"Parent": null, "Parent": null,
@@ -298,10 +298,10 @@ TestDoc Case 7:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/*! doc 1 */" "Text": "/*! doc 1 */\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": "/*! doc 2 */" "Text": "/*! doc 2 */\n"
}] }]
}, },
"Parent": null, "Parent": null,
@@ -350,10 +350,10 @@ TestDoc Case 8:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/** doc 1 */" "Text": "/** doc 1 */\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": "/** doc 1 */" "Text": "/** doc 1 */\n"
}] }]
}, },
"Parent": null, "Parent": null,
@@ -402,16 +402,16 @@ TestDoc Case 9:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/**" "Text": "/**\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " * doc 1" "Text": " * doc 1\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " * doc 2" "Text": " * doc 2\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " */" "Text": " */\n"
}] }]
}, },
"Parent": null, "Parent": null,
@@ -478,7 +478,7 @@ TestDoc Case 10:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/// doc" "Text": "/// doc\n"
}] }]
}, },
"Comment": null, "Comment": null,
@@ -500,7 +500,7 @@ TestDoc Case 10:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "///< comment" "Text": "///< comment\n"
}] }]
}, },
"IsStatic": false, "IsStatic": false,
@@ -521,7 +521,7 @@ TestDoc Case 10:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/*!< comment */" "Text": "/*!< comment */\n"
}] }]
}, },
"IsStatic": false, "IsStatic": false,
@@ -572,13 +572,13 @@ TestDoc Case 11:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/** " "Text": "/** \n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " * static field doc" "Text": " * static field doc\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " */" "Text": " */\n"
}] }]
}, },
"Comment": null, "Comment": null,
@@ -600,7 +600,7 @@ TestDoc Case 11:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/*!< static field comment */" "Text": "/*!< static field comment */\n"
}] }]
}, },
"IsStatic": true, "IsStatic": true,
@@ -620,13 +620,13 @@ TestDoc Case 11:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/** " "Text": "/** \n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " * field doc" "Text": " * field doc\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " */" "Text": " */\n"
}] }]
}, },
"Comment": null, "Comment": null,
@@ -648,7 +648,7 @@ TestDoc Case 11:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "///< field comment" "Text": "///< field comment\n"
}] }]
}, },
"IsStatic": false, "IsStatic": false,
@@ -669,7 +669,7 @@ TestDoc Case 11:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/*!< protected field comment */" "Text": "/*!< protected field comment */\n"
}] }]
}, },
"IsStatic": false, "IsStatic": false,
@@ -690,13 +690,13 @@ TestDoc Case 11:
"_Type": "CommentGroup", "_Type": "CommentGroup",
"List": [{ "List": [{
"_Type": "Comment", "_Type": "Comment",
"Text": "/** " "Text": "/** \n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " * method doc" "Text": " * method doc\n"
}, { }, {
"_Type": "Comment", "_Type": "Comment",
"Text": " */" "Text": " */\n"
}] }]
}, },
"Parent": { "Parent": {

View File

@@ -4,6 +4,7 @@ import (
"errors" "errors"
"github.com/goplus/llgo/c/cjson" "github.com/goplus/llgo/c/cjson"
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
) )
type Context struct { type Context struct {
@@ -49,7 +50,7 @@ func (p *Context) processFile(path string) error {
} }
func (p *Context) parseFile(path string) ([]*FileEntry, error) { func (p *Context) parseFile(path string) ([]*FileEntry, error) {
converter, err := NewConverter(&Config{ converter, err := NewConverter(&clangutils.Config{
File: path, File: path,
Temp: false, Temp: false,
IsCpp: p.IsCpp, IsCpp: p.IsCpp,