diff --git a/cl/class.go b/cl/class.go index 4ef1f6b9..325dc7bb 100644 --- a/cl/class.go +++ b/cl/class.go @@ -82,9 +82,9 @@ func compileClass(ctx *pkgCtx, this *classCtx) { } } -func newTypeParams(ctx *pkgCtx, pkg *types.Package, cls clang.Cursor, feats *int) []*types.TypeParam { +func newTypeParams(ctx *pkgCtx, pkg *types.Package, cls clang.Cursor) (ret []*types.TypeParam, quietIgnore bool) { idx := 0 - ret := make([]*types.TypeParam, 0, 2) + ret = make([]*types.TypeParam, 0, 2) clang.VisitChildren(cls, func(decl, parent clang.Cursor) clang.ChildVisitResult { switch decl.Kind { case lc.Cursor_TemplateTypeParameter: @@ -96,13 +96,14 @@ func newTypeParams(ctx *pkgCtx, pkg *types.Package, cls clang.Cursor, feats *int objName := types.NewTypeName(0, pkg, name, nil) ret = append(ret, types.NewTypeParam(objName, ctx.any())) case lc.Cursor_NonTypeTemplateParameter, lc.Cursor_TemplateTemplateParameter: - *feats |= featIgnored + quietIgnore = true + fallthrough default: return clang.Break } return clang.Continue }) - return ret + return } func loadTemplateClass(ctx *pkgCtx, cls clang.Cursor, ns string, parent *scopeCtx) { @@ -123,10 +124,11 @@ func compileTemplateClass(ctx *pkgCtx, obj *templateClass, parent *scopeCtx) { pkg := ctx.pkg pkgTypes := pkg.Types - feats := 0 - tparams := newTypeParams(ctx, pkgTypes, cls, &feats) - if feats&featIgnored != 0 || obj.order() >= 0 { - ctx.logf(cls, "class %s: unsupported template params, skipped", clang.String(cls)) + tparams, quietIgnore := newTypeParams(ctx, pkgTypes, cls) + if quietIgnore || obj.order() >= 0 { + if debugQuietIgnore { + ctx.logf(cls, "class %s: unsupported template params, ignored", clang.String(cls)) + } return } @@ -188,8 +190,8 @@ func newType(ctx *pkgCtx, cls clang.Cursor, clsName string, kind typeTag) (ret t func initClassType(ctx *pkgCtx, typDecl typDecl, cls clang.Cursor, clsName string, tparams []*types.TypeParam, parent *scopeCtx) bool { feats := 0 initClassTypeEx(ctx, typDecl, cls, clsName, tparams, parent, &feats) - if feats&featIgnored != 0 { - ctx.logf(cls, "class %s: unsupported features, skipped", clang.String(cls)) + if feats&featAllIgnore != 0 { + ctx.ignoref(feats, cls, "class %s: unsupported features, ignored", clang.String(cls)) typDecl.Delete() return false } @@ -217,7 +219,7 @@ func initClassTypeEx(ctx *pkgCtx, typDecl typDecl, cls clang.Cursor, clsName str loadClassMember(ctx, pkgTypes, this, clsName, decl, feats) return clang.Continue }) - if *feats&featIgnored != 0 { + if *feats&featAllIgnore != 0 { return } // Establish the layout at offset 0, following the C++ Itanium ABI. A @@ -297,7 +299,7 @@ func loadClassMember(ctx *pkgCtx, pkg *types.Package, this *classCtx, clsName st } } if !anonymous { - if fldType = toTypeEx(ctx, pkg, ft, flagIsVarDef, feats, this.scope()); *feats&featIgnored != 0 { + if fldType = toTypeEx(ctx, pkg, ft, flagIsVarDef, feats, this.scope()); *feats&featAllIgnore != 0 { return } } @@ -481,10 +483,11 @@ func baseClass(ctx *pkgCtx, decl clang.Cursor, feats *int) *types.TypeName { return t } case lc.Type_Unexposed: - *feats |= featIgnored + ctx.logf(decl, "baseClass %s: with unexposed type, skipped", clang.String(decl)) + *feats |= featExplicitIgnore return nil } - ctx.panicf(decl, "baseClass: unknown base class type - %s (%d)", clang.String(t), t.Kind) + ctx.panicf(decl, "baseClass %s: unknown base class - %s (%d)", clang.String(decl), clang.String(t), t.Kind) return nil } diff --git a/cl/compile.go b/cl/compile.go index 870e5b2b..e7a6a876 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -30,17 +30,20 @@ import ( const ( DbgFlagCompileDecl = 1 << iota DbgFlagMajorProc - DbgFlagAll = DbgFlagCompileDecl | DbgFlagMajorProc + DbgFlagQuietIgnore + DbgFlagAll = DbgFlagCompileDecl | DbgFlagMajorProc | DbgFlagQuietIgnore ) var ( debugCompileDecl bool debugMajorProc bool + debugQuietIgnore bool ) func SetDebug(flags int) { debugCompileDecl = (flags & DbgFlagCompileDecl) != 0 debugMajorProc = (flags & DbgFlagMajorProc) != 0 + debugQuietIgnore = (flags & DbgFlagQuietIgnore) != 0 } // ----------------------------------------------------------------------------- diff --git a/cl/ctx.go b/cl/ctx.go index 056e7361..eac9726a 100644 --- a/cl/ctx.go +++ b/cl/ctx.go @@ -159,6 +159,12 @@ type pkgCtx struct { keepDoc bool } +func (p *pkgCtx) ignoref(feats int, decl clang.Cursor, format string, args ...any) { + if feats&featQuietIgnore == 0 || debugQuietIgnore { + p.logf(decl, format, args...) + } +} + func (p *pkgCtx) logf(decl clang.Cursor, format string, args ...any) { pos := p.fset.Position(goNodePos(p, decl)) log.Printf("%s: %s", pos, fmt.Sprintf(format, args...)) @@ -271,9 +277,9 @@ func (p *pkgCtx) addType(kind typeTag, decl clang.Cursor, typNamed *types.Named) } } -func (p *pkgCtx) ignoreType(cName string) { +func (p *pkgCtx) ignoreType(cName string, feats int) { if _, ok := p.types[cName]; !ok { - p.types[cName] = typeObj{nil, featIgnored} + p.types[cName] = typeObj{nil, feats} } } diff --git a/cl/enum.go b/cl/enum.go index 1c6ededb..488e7f02 100644 --- a/cl/enum.go +++ b/cl/enum.go @@ -66,7 +66,7 @@ func loadEnum(ctx *pkgCtx, decl clang.Cursor, ns string) { feats := 0 underType := toTypeEx(ctx, pkgTypes, typ, flagIsTypeDef, &feats, nil) - if feats&featIgnored != 0 { + if feats&featAllIgnore != 0 { ctx.panicf(decl, "enum %s: unsupported underlying type %s (%d)", name, clang.String(typ), typ.Kind) } typDecl.InitType(pkg, underType) diff --git a/cl/func.go b/cl/func.go index 62f4a694..44498d09 100644 --- a/cl/func.go +++ b/cl/func.go @@ -89,14 +89,14 @@ func compileFuncOrMethod(ctx *pkgCtx, obj *funcObj, this *classCtx) { scope := this.scope() params, variadic := newParams(ctx, pkgTypes, fn, &feats, scope) results := toFuncResults(ctx, pkgTypes, fn.ResultType(), &feats, scope) - if feats&featIgnored != 0 { - ctx.logf(fn, "func %s: function with unsupported features, skipped", clang.String(fn)) + if feats&featAllIgnore != 0 { + ctx.ignoref(feats, fn, "func %s: function with unsupported features, ignored", clang.String(fn)) return } if fn.IsFunctionInlined() != 0 { if ctx.cflags == "" { - ctx.logf(fn, "func %s: inline function but no CFlags in config, skipped", clang.String(fn)) + ctx.ignoref(InlineFuncIgnore, fn, "func %s: inline function but no CFlags in config, ignored", clang.String(fn)) return } manglingName = wrapInlineFunc(ctx, manglingName, fn, this) diff --git a/cl/type.go b/cl/type.go index 202ff1d4..78dfc929 100644 --- a/cl/type.go +++ b/cl/type.go @@ -58,13 +58,23 @@ func newPointer(ctx *pkgCtx, typ types.Type) types.Type { const ( featHasCallback = 1 << iota - featIgnored + featExplicitIgnore + featQuietIgnore + featAllIgnore = featExplicitIgnore | featQuietIgnore +) + +const ( + QuietIgnoreInline = featQuietIgnore +) + +var ( + InlineFuncIgnore = featExplicitIgnore ) func toType(ctx *pkgCtx, pkg *types.Package, typ lc.Type, flags int, scope *scopeCtx) types.Type { var feats int ret := toTypeEx(ctx, pkg, typ, flags, &feats, scope) - if feats&featIgnored != 0 { + if feats&featAllIgnore != 0 { panic("unsupported type - " + clang.String(typ)) } return ret @@ -129,7 +139,7 @@ func toTypeEx(ctx *pkgCtx, pkg *types.Package, typ lc.Type, flags int, feats *in if o, ok := ctx.types[cName]; ok { if o.feats != 0 { *feats |= o.feats - if o.feats&featIgnored != 0 { + if o.feats&featAllIgnore != 0 { return types.Typ[types.Invalid] // ignored type } } @@ -167,14 +177,13 @@ func toTypeEx(ctx *pkgCtx, pkg *types.Package, typ lc.Type, flags int, feats *in case lc.Type_LongDouble: return ctx.basicTyp(cLongDouble) case lc.Type_BlockPointer: - ctx.logtf(typ, "type %s: C blocks (closures) are unsupported, ignored", clang.String(typ)) - *feats |= featIgnored + *feats |= featQuietIgnore // will always be ignored return types.Typ[types.Invalid] default: ctx.logtf(typ, "toType: unknown kind - %v", typ.Kind) } ctx.logtf(typ, "unsupported type - %s", clang.String(typ)) - *feats |= featIgnored + *feats |= featExplicitIgnore return types.Typ[types.Invalid] } diff --git a/cl/typedef.go b/cl/typedef.go index e90d4eef..001dfa7c 100644 --- a/cl/typedef.go +++ b/cl/typedef.go @@ -30,16 +30,14 @@ func loadTypedef(ctx *pkgCtx, decl clang.Cursor, ns string, scope *scopeCtx) { cName := clang.String(decl.Type()) localName := clang.String(decl) // TODO(xsw): use full name with namespace if ctx.isTypeIgnored(localName) { - if debugCompileDecl { - log.Println("typedef", cName, "- ignored") - } - ctx.ignoreType(cName) + ctx.ignoref(featQuietIgnore, decl, "typedef %s: ignored by config", localName) + ctx.ignoreType(cName, featQuietIgnore) return } origName := nameWithNS(localName, ns) if decl.Kind == lc.Cursor_TypeAliasTemplateDecl { - ctx.logf(decl, "typedef %s: template type alias, skipped", origName) + ctx.logf(decl, "typedef %s: template type alias, skipped", localName) return } @@ -52,9 +50,14 @@ func loadTypedef(ctx *pkgCtx, decl clang.Cursor, ns string, scope *scopeCtx) { feats := 0 tunder := toTypeEx(ctx, pkgTypes, underlying, flagIsTypeDef, &feats, scope) - if feats&featIgnored != 0 || isTypedefUnsupported(tunder) { - ctx.logf(decl, "typedef %s: unsupported underlying type, skipped", origName) - ctx.ignoreType(cName) + if feats&featQuietIgnore != 0 || isTypedefUnsupported(tunder) { + ctx.ignoref(featQuietIgnore, decl, "typedef %s: unsupported underlying type, ignored", localName) + ctx.ignoreType(cName, featQuietIgnore) + return + } + if feats&featExplicitIgnore != 0 { + ctx.logf(decl, "typedef %s: unsupported underlying type, skipped", localName) + ctx.ignoreType(cName, featExplicitIgnore) return } diff --git a/cl/var.go b/cl/var.go index 0f05609a..b3176f02 100644 --- a/cl/var.go +++ b/cl/var.go @@ -78,8 +78,8 @@ func compileVar(ctx *pkgCtx, decl clang.Cursor, ns string) { feats := 0 typ := toTypeEx(ctx, pkgTypes, decl.Type(), flagIsVarDef, &feats, nil) - if feats&featIgnored != 0 { - ctx.logf(decl, "var %s: unsupported type, skipped", origName) + if feats&featAllIgnore != 0 { + ctx.ignoref(feats, decl, "var %s: unsupported type, ignored", localName) return } diff --git a/cmd/llcppg/gen.go b/cmd/llcppg/gen.go index c618343b..ce1e9cfd 100644 --- a/cmd/llcppg/gen.go +++ b/cmd/llcppg/gen.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/goplus/gogen" + "github.com/goplus/llcppg/cl" "github.com/goplus/llcppg/clang" "github.com/goplus/llcppg/tool" "github.com/qiniu/x/errors" @@ -44,6 +45,10 @@ func Gen(destDir, srcDir string, index clang.Index) (err error) { } mainPkgName := cfg.Name + if cfg.IgnoreInline { + cl.InlineFuncIgnore = cl.QuietIgnoreInline // quiet ignore inline functions + } + if len(cfg.Pkgs) == 0 { return genPkg(destDir, srcDir, mainPkgName, index, &cfg) } diff --git a/tool/config.go b/tool/config.go index 986e5b38..50278909 100644 --- a/tool/config.go +++ b/tool/config.go @@ -51,6 +51,7 @@ type Config struct { MacroIgnore []string `json:"MacroIgnore"` // C/C++ macro names to ignore NSIgnore []string `json:"NSIgnore"` // namespaces (Go style names) to ignore Pkgs []string `json:"Pkgs"` // sub-packages to generate, optional + IgnoreInline bool `json:"IgnoreInline"` // quietly ignore inline functions GroupSubdir bool `json:"GroupSubdir"` // treats sub-directory files as a single file }