From a90da481f317930d686971859b64995fb47e89c8 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 1 Oct 2026 02:46:15 +0800 Subject: [PATCH 1/2] cl: conf.MacroIgnore; conf.TypeAbbr support string/[]string (see ctx.funcName); loadEnum: support fwd decl --- cl/_testcpp/enum/in.h | 11 +++++++++- cl/_testcpp/enum/out.go | 9 ++++++++- cl/_testpp/macro/in.cfg | 3 +++ cl/_testpp/macro/in.h | 1 + cl/cltest/cltest.go | 1 + cl/compile.go | 18 ++++++++++------- cl/compile_test.go | 1 + cl/ctx.go | 29 ++++++++++++++++++++++++--- cl/enum.go | 27 ++++++++++++++++--------- cl/preprocessor.go | 8 ++++++++ cl/type.go | 26 ++++++++++++++---------- go.mod | 2 +- go.sum | 4 ++-- tool/_testc/clang-c-22.1.8/llcppg.cfg | 2 +- tool/config.go | 5 +++-- tool/gen.go | 1 + tool/gen_test.go | 1 + 17 files changed, 111 insertions(+), 38 deletions(-) create mode 100644 cl/_testpp/macro/in.cfg diff --git a/cl/_testcpp/enum/in.h b/cl/_testcpp/enum/in.h index 9a58d42e..44b30b1a 100644 --- a/cl/_testcpp/enum/in.h +++ b/cl/_testcpp/enum/in.h @@ -1,8 +1,17 @@ -enum Global { +enum Global : int; + +enum Global : int { GA, GB }; +enum class Local : int; + +enum class Local : int { + LA, + LB +}; + namespace bar { enum Color { Red, diff --git a/cl/_testcpp/enum/out.go b/cl/_testcpp/enum/out.go index e250a65a..c7c2eca5 100644 --- a/cl/_testcpp/enum/out.go +++ b/cl/_testcpp/enum/out.go @@ -2,13 +2,20 @@ package foo import "github.com/goplus/lib/c" -type Global c.Uint +type Global c.Int const ( GA Global = 0 GB Global = 1 ) +type Local c.Int + +const ( + Local_LA Local = 0 + Local_LB Local = 1 +) + type BarColor c.Uint const ( diff --git a/cl/_testpp/macro/in.cfg b/cl/_testpp/macro/in.cfg new file mode 100644 index 00000000..53cce11b --- /dev/null +++ b/cl/_testpp/macro/in.cfg @@ -0,0 +1,3 @@ +{ + "MacroIgnore": ["MASK2"] +} diff --git a/cl/_testpp/macro/in.h b/cl/_testpp/macro/in.h index 5d6fcd4c..0a58ab7a 100644 --- a/cl/_testpp/macro/in.h +++ b/cl/_testpp/macro/in.h @@ -12,6 +12,7 @@ #define FVAL (TRUE * 3.14) #define MASK (~FALSE) +#define MASK2 (~FALSE) #define TWO (THREE * TRUE + -TRUE) typedef char BOOL, *PBOOL; diff --git a/cl/cltest/cltest.go b/cl/cltest/cltest.go index 1e49b303..65d74c15 100644 --- a/cl/cltest/cltest.go +++ b/cl/cltest/cltest.go @@ -34,6 +34,7 @@ type Config struct { WrapFileHeader string `json:"WrapFileHeader"` CFlags string `json:"CFlags"` Files []string `json:"Files"` + MacroIgnore []string `json:"MacroIgnore"` KeepDoc bool `json:"KeepDoc"` } diff --git a/cl/compile.go b/cl/compile.go index d4520b7f..1783d66d 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -112,12 +112,15 @@ type Config struct { // to be ignored (optional). NSIgnore []string + // MacroIgnore specifies a list of C/C++ macro names to be ignored (optional). + MacroIgnore []string + // TypeIgnore specifies a list of C/C++ type names to be ignored (optional). TypeIgnore []string - // TypeAbbr specifies a mapping of Go type name to its abbreviated name. The abbreviated - // name will be used in function names (optional). - TypeAbbr map[string]string + // TypeAbbr specifies a mapping of Go type name to its abbreviated name(s). The abbreviated + // name(s) can be a `string` or `[]string`. They will be used in function names (optional). + TypeAbbr map[string]any // TypeAbbrSuffix specifies the suffix to remove from Go type name when generating function // names. It is only valid for types that are not present in TypeAbbr (optional). @@ -219,9 +222,10 @@ func NewPackage(pkgPath, pkgName string, files []Source, conf *Config) (ret Pack keepDoc: !conf.DontKeepDoc, stdRecvName: conf.UseStdRecvName, cflags: conf.CFlags, wrapFileHeader: conf.WrapFileHeader, typeAbbr: conf.TypeAbbr, typeAbbrSuffix: conf.TypeAbbrSuffix, - typePrefix: conf.TypePrefix, typeSuffix: conf.TypeSuffix, fnPrefix: conf.FuncPrefix, - enumPrefix: conf.EnumPrefix, macroPrefix: conf.MacroPrefix, varPrefix: conf.VarPrefix, - nsIgnores: conf.NSIgnore, typeIgnores: conf.TypeIgnore, rename: rename, + typePrefix: conf.TypePrefix, typeSuffix: conf.TypeSuffix, + fnPrefix: conf.FuncPrefix, enumPrefix: conf.EnumPrefix, + macroPrefix: conf.MacroPrefix, varPrefix: conf.VarPrefix, rename: rename, + nsIgnores: conf.NSIgnore, macroIgnore: conf.MacroIgnore, typeIgnores: conf.TypeIgnore, classes: conf.Class, nonClasses: conf.NonClass, typdecls: typdecls, pkgOf: conf.PackageOf, nameLookup: nameLookup, pubLookup: conf.PubFileLookup, fileBases: make(map[clang.File]int), fns: make(map[string]*funcObj), @@ -312,7 +316,7 @@ func loadDecl(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor, ns string) { // TODO(xsw): ignore for now case lc.Cursor_ClassTemplate, lc.Cursor_ClassTemplatePartialSpecialization: loadTemplateClass(ctx, decl, ns, nil) - case lc.Cursor_UnexposedDecl: + case lc.Cursor_UnexposedDecl, lc.Cursor_UnexposedAttr: // noop default: ctx.panicf(decl, "loadDecl: unknown kind - %v", decl.Kind) diff --git a/cl/compile_test.go b/cl/compile_test.go index 5a2e0367..fd8753ce 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -88,6 +88,7 @@ func testFromDir(t *testing.T, sel, relDir string, lang cl.Language) { LLGoPackage: conf.LLGoPackage, Language: lang, WrapFileHeader: conf.WrapFileHeader, + MacroIgnore: conf.MacroIgnore, CFlags: conf.CFlags, NameLookup: nil, DontKeepDoc: !conf.KeepDoc, diff --git a/cl/ctx.go b/cl/ctx.go index 0e74262d..c0229889 100644 --- a/cl/ctx.go +++ b/cl/ctx.go @@ -128,9 +128,10 @@ type pkgCtx struct { typeSuffix []string classes []string // typedef names to be treated as classes nonClasses []string // typedef names to be treated as non-classes - typeAbbr map[string]string // Go type name => abbreviated name, used in function names + typeAbbr map[string]any // Go type name => abbreviated name(s), used in function names rename map[string]string // C/C++ name => Go name typeIgnores []string // C/C++ type names to be ignored + macroIgnore []string // C/C++ macro names to be ignored nsIgnores []string // Go style namespace names to be ignored nameLookup func(manglingName string) (archivePath string, ok bool) @@ -280,6 +281,10 @@ func (p *pkgCtx) isTypeIgnored(cName string) bool { return contains(trimTypeTag(cName), p.typeIgnores) } +func (p *pkgCtx) isMacroIgnored(name string) bool { + return contains(name, p.macroIgnore) +} + func (p *pkgCtx) isNSIgnored(ns string) bool { return contains(ns, p.nsIgnores) } @@ -342,12 +347,30 @@ func (p *pkgCtx) funcName(name string, order int, typName, typCName string, glob if !strings.HasPrefix(name, "XGo_") { // avoid rewriting XGo_xxx names name = p.cstyleToGo(name, true) if typName != "" { + var typSuffix []string if v, ok := p.typeAbbr[typName]; ok { // Go type name => abbreviated name - typName = v + switch v := v.(type) { + case string: + typName = v + typSuffix = []string{v} + case []any: + if n := len(v); n > 0 { + abbrs := make([]string, n) + for i, v := range v { + abbrs[i] = v.(string) + } + typName = abbrs[n-1] + typSuffix = abbrs + } + default: + panic(fmt.Errorf("invalid TypeAbbr for %q: %v", typName, v)) + } } else { typName = rmSuffix(typName, p.typeAbbrSuffix) + typSuffix = []string{typName} } - name = cutMethodPrefix(strings.TrimSuffix(name, typName), typName) + name = rmSuffix(name, typSuffix) + name = cutMethodPrefix(name, typName) } } if order >= 0 { diff --git a/cl/enum.go b/cl/enum.go index 16ce72c8..ba28aef9 100644 --- a/cl/enum.go +++ b/cl/enum.go @@ -43,26 +43,35 @@ func loadEnum(ctx *pkgCtx, decl clang.Cursor, ns string) { origName := nameWithNS(name, ns) anonymous := decl.IsAnonymous() != 0 scoped := decl.EnumDeclIsScoped() != 0 + definition := decl.IsCursorDefinition() != 0 // TODO(xsw): rename to IsDefinition typ := decl.EnumDeclIntegerType() if debugCompileDecl { - log.Println("enum", origName, clang.String(typ), "anonymous:", anonymous, "scoped:", scoped) + log.Println( + "enum", origName, clang.String(typ), "anonymous:", anonymous, + "scoped:", scoped, "definition:", definition) } pkg := ctx.pkg pkgTypes := pkg.Types var enumType types.Type + var typDecl, ok = ctx.typdecls[origName] + if !ok { + clsName := ctx.typeName(origName, true) + typDecl = newType(ctx, decl, clsName, tagEnum) + ctx.typdecls[origName] = typDecl + + underType := toType(ctx, pkgTypes, typ, flagIsTypeDef, nil) + typDecl.InitType(pkg, underType) + } + if !definition { + return // declaration only, no definition + } if !anonymous { - typDefs := pkg.NewTypeDefs() if doc := ctx.docCommentGroup(decl); doc != nil { - typDefs.SetComments(doc) + typDecl.defs.SetComments(doc) } - typeName := ctx.typeName(origName, true) - typDecl := typDefs.NewType(typeName, goNode(ctx, decl)) - underType := toType(ctx, pkgTypes, typ, flagIsTypeDef, nil) - typNamed := typDecl.InitType(pkg, underType) - ctx.addType(tagEnum, decl, typNamed) - enumType = typNamed + enumType = typDecl.Type() } defs := pkg.NewConstDefs(pkgTypes.Scope()) diff --git a/cl/preprocessor.go b/cl/preprocessor.go index 02a8948c..8ef74740 100644 --- a/cl/preprocessor.go +++ b/cl/preprocessor.go @@ -56,7 +56,15 @@ func loadMacro(ctx *pkgCtx, decl clang.Cursor) { if decl.IsMacroFunctionLike() != 0 { return } + origName := clang.String(decl) + if ctx.isMacroIgnored(origName) { + if debugCompileDecl { + log.Println("macro", origName, "- ignored") + } + return + } + tu := clang.TU(decl) tokens, dispose := tu.Tokenize(decl.Extent()) defer dispose() diff --git a/cl/type.go b/cl/type.go index 2fd30244..bea35254 100644 --- a/cl/type.go +++ b/cl/type.go @@ -164,6 +164,8 @@ func toTypeEx(ctx *pkgCtx, pkg *types.Package, typ lc.Type, flags int, feats *in if t, ok := scope.lookupType(name); ok { return t } + 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 @@ -239,21 +241,23 @@ const ( cFloat cDouble cPointer + cLongDouble cBasicMax ) var ctypBasic = [cBasicMax]string{ - cVoid: "Void", - cChar: "Char", - cInt: "Int", - cUint: "Uint", - cLong: "Long", - cUlong: "Ulong", - cLongLong: "LongLong", - cUlongLong: "UlongLong", - cFloat: "Float", - cDouble: "Double", - cPointer: "Pointer", + cVoid: "Void", + cChar: "Char", + cInt: "Int", + cUint: "Uint", + cLong: "Long", + cUlong: "Ulong", + cLongLong: "LongLong", + cUlongLong: "UlongLong", + cFloat: "Float", + cDouble: "Double", + cPointer: "Pointer", + cLongDouble: "LongDouble", } // ----------------------------------------------------------------------------- diff --git a/go.mod b/go.mod index 6dfdc46a..777d5399 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.27.0 // llgo 1.0 require ( github.com/goplus/gogen v1.25.3 - github.com/goplus/lib v0.5.4 + github.com/goplus/lib v0.5.5 github.com/goplus/mod v0.22.1 github.com/llarhub/clang-c v0.7.0 github.com/qiniu/x v1.18.3 diff --git a/go.sum b/go.sum index 37522e1b..1e1a7a2b 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/goplus/gogen v1.25.3 h1:g8VWgNcCwTG9DFs08umVNtxl/BSLHH1cbvqWzyxrPVk= github.com/goplus/gogen v1.25.3/go.mod h1:Y7ulYW3wonQ3d9er00b0uGFEV/IUZa6okWJZh892ACQ= -github.com/goplus/lib v0.5.4 h1:Ltrj+lY844/jx0nJqCRQEq3YzBkHb3jBjCQZWFUdlTc= -github.com/goplus/lib v0.5.4/go.mod h1:SgJv3oPqLLHCu0gcL46ejOP3x7/2ry2Jtxu7ta32kp0= +github.com/goplus/lib v0.5.5 h1:COcqsafjaXBI6ikcyJgnc7l9Hu03K8kymUSIZtXNTz8= +github.com/goplus/lib v0.5.5/go.mod h1:SgJv3oPqLLHCu0gcL46ejOP3x7/2ry2Jtxu7ta32kp0= github.com/goplus/mod v0.22.1 h1:3GQZqKlcQAiMpRUDAHvFryGYie+mT0JMjguEqOtIjkE= github.com/goplus/mod v0.22.1/go.mod h1:APrczG2FtFcQelU4vTq9xw+GrVs4sPPKnRfGidWBlXY= github.com/llarhub/clang-c v0.7.0 h1:YkO1FR1R1ScKJijF1PUVIpHnIC4uNgsSg/7CLzEBpFE= diff --git a/tool/_testc/clang-c-22.1.8/llcppg.cfg b/tool/_testc/clang-c-22.1.8/llcppg.cfg index 7990dbcf..eeeab234 100644 --- a/tool/_testc/clang-c-22.1.8/llcppg.cfg +++ b/tool/_testc/clang-c-22.1.8/llcppg.cfg @@ -13,6 +13,7 @@ "TypeAbbr": { "IdxLoc": "IndexLoc", "TUResourceUsageKind": "TUResourceUsage", + "IndexOptions": ["WithOptions"], "SourceLocation": "Location", "SourceRange": "Range" }, @@ -24,7 +25,6 @@ "clang_sortCodeCompletionResults": "Sort", "clang_getNumCompletionChunks": "NumChunks", "clang_codeCompleteAt": "CodeCompleteAt", - "clang_createIndexWithOptions": "CreateIndex", "clang_createCXCursorSet": "CreateCursorSet", "getCString": "CStr" }, diff --git a/tool/config.go b/tool/config.go index c79f9fc1..5476f08c 100644 --- a/tool/config.go +++ b/tool/config.go @@ -44,10 +44,11 @@ type Config struct { MacroPrefix []string `json:"MacroPrefix"` // macro prefix to remove TypePrefix []string `json:"TypePrefix"` // type prefix to remove TypeSuffix []string `json:"TypeSuffix"` // type suffix to remove - TypeAbbrSuffix []string `json:"TypeAbbrSuffix"` // type abbr suffix to remove, only valid for types that is not in TypeAbbr - TypeAbbr map[string]string `json:"TypeAbbr"` // Go type name to its abbr, used in function names + TypeAbbrSuffix []string `json:"TypeAbbrSuffix"` // type abbr suffix to remove, only valid for types that are not present in TypeAbbr + TypeAbbr map[string]any `json:"TypeAbbr"` // Go type name to its abbr(s), used in function names Rename map[string]string `json:"Rename"` // renaming of C/C++ names to Go names TypeIgnore []string `json:"TypeIgnore"` // C/C++ type names to ignore + 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 } diff --git a/tool/gen.go b/tool/gen.go index 698b9de7..80a322b2 100644 --- a/tool/gen.go +++ b/tool/gen.go @@ -178,6 +178,7 @@ func (cfg *Config) NewPackage(pkgPath, pkgName, workDir string, index clang.Inde TypeAbbrSuffix: cfg.TypeAbbrSuffix, Rename: cfg.Rename, TypeIgnore: cfg.TypeIgnore, + MacroIgnore: cfg.MacroIgnore, NSIgnore: cfg.NSIgnore, DefaultGoFile: "llcppg.i.go", UseStdRecvName: true, diff --git a/tool/gen_test.go b/tool/gen_test.go index 3f388584..7a7a051d 100644 --- a/tool/gen_test.go +++ b/tool/gen_test.go @@ -136,6 +136,7 @@ func testSingleFile(t *testing.T, idx clang.Index, pkgDir, headerDir, headerFile TypeAbbrSuffix: conf.TypeAbbrSuffix, Rename: conf.Rename, TypeIgnore: conf.TypeIgnore, + MacroIgnore: conf.MacroIgnore, NSIgnore: conf.NSIgnore, NameLookup: nil, PubFileLookup: func(pkgPath string) (pubFile string, ok bool) { From 2cfd25aaca6635a3acc1f9cfcf0dfc1f8a498ae9 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 1 Oct 2026 03:54:24 +0800 Subject: [PATCH 2/2] cl: loadEnum bugfix; tool: cfg.NewPackage refactor --- cl/compile.go | 2 +- cl/enum.go | 18 +++--- .../system/AMDHSAKernelDescriptor.go | 24 ++++---- .../llvm-22.1.8-support/system/Atomic.go | 6 +- tool/gen.go | 58 +++++++++---------- 5 files changed, 57 insertions(+), 51 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 1783d66d..44f0f3d5 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -119,7 +119,7 @@ type Config struct { TypeIgnore []string // TypeAbbr specifies a mapping of Go type name to its abbreviated name(s). The abbreviated - // name(s) can be a `string` or `[]string`. They will be used in function names (optional). + // name(s) can be a name or name list. They will be used in function names (optional). TypeAbbr map[string]any // TypeAbbrSuffix specifies the suffix to remove from Go type name when generating function diff --git a/cl/enum.go b/cl/enum.go index ba28aef9..e3a8247f 100644 --- a/cl/enum.go +++ b/cl/enum.go @@ -54,15 +54,19 @@ func loadEnum(ctx *pkgCtx, decl clang.Cursor, ns string) { pkg := ctx.pkg pkgTypes := pkg.Types + var ok bool + var typDecl typDecl var enumType types.Type - var typDecl, ok = ctx.typdecls[origName] - if !ok { - clsName := ctx.typeName(origName, true) - typDecl = newType(ctx, decl, clsName, tagEnum) - ctx.typdecls[origName] = typDecl + if !anonymous { + typDecl, ok = ctx.typdecls[origName] + if !ok { + clsName := ctx.typeName(origName, true) + typDecl = newType(ctx, decl, clsName, tagEnum) + ctx.typdecls[origName] = typDecl - underType := toType(ctx, pkgTypes, typ, flagIsTypeDef, nil) - typDecl.InitType(pkg, underType) + underType := toType(ctx, pkgTypes, typ, flagIsTypeDef, nil) + typDecl.InitType(pkg, underType) + } } if !definition { return // declaration only, no definition diff --git a/tool/_testcpp/llvm-22.1.8-support/system/AMDHSAKernelDescriptor.go b/tool/_testcpp/llvm-22.1.8-support/system/AMDHSAKernelDescriptor.go index 4c477a83..0c0d4640 100644 --- a/tool/_testcpp/llvm-22.1.8-support/system/AMDHSAKernelDescriptor.go +++ b/tool/_testcpp/llvm-22.1.8-support/system/AMDHSAKernelDescriptor.go @@ -276,18 +276,18 @@ const ( ) type AMDHSAKernelDescriptor struct { - GroupSegmentFixedSize c.Int - PrivateSegmentFixedSize c.Int - KernargSize c.Int - Reserved0 [4]c.Int - KernelCodeEntryByteOffset c.Int - Reserved1 [20]c.Int - ComputePgmRsrc3 c.Int - ComputePgmRsrc1 c.Int - ComputePgmRsrc2 c.Int - KernelCodeProperties c.Int - KernargPreload c.Int - Reserved3 [4]c.Int + GroupSegmentFixedSize c.Uint32T + PrivateSegmentFixedSize c.Uint32T + KernargSize c.Uint32T + Reserved0 [4]c.Uint8T + KernelCodeEntryByteOffset c.Int64T + Reserved1 [20]c.Uint8T + ComputePgmRsrc3 c.Uint32T + ComputePgmRsrc1 c.Uint32T + ComputePgmRsrc2 c.Uint32T + KernelCodeProperties c.Uint16T + KernargPreload c.Uint16T + Reserved3 [4]c.Uint8T } const ( diff --git a/tool/_testcpp/llvm-22.1.8-support/system/Atomic.go b/tool/_testcpp/llvm-22.1.8-support/system/Atomic.go index 02ab0b5f..0abb0dd7 100644 --- a/tool/_testcpp/llvm-22.1.8-support/system/Atomic.go +++ b/tool/_testcpp/llvm-22.1.8-support/system/Atomic.go @@ -7,8 +7,10 @@ import ( _ "unsafe" ) +type SysCasFlag = c.Uint32T + //go:linkname SysMemoryFence C._ZN4llvm3sys11MemoryFenceEv func SysMemoryFence() -//go:linkname SysCompareAndSwap C._ZN4llvm3sys14CompareAndSwapEPViii -func SysCompareAndSwap(ptr *c.Int, new_value c.Int, old_value c.Int) c.Int +//go:linkname SysCompareAndSwap C._ZN4llvm3sys14CompareAndSwapEPVjjj +func SysCompareAndSwap(ptr *SysCasFlag, new_value SysCasFlag, old_value SysCasFlag) SysCasFlag diff --git a/tool/gen.go b/tool/gen.go index 80a322b2..294b20f0 100644 --- a/tool/gen.go +++ b/tool/gen.go @@ -95,27 +95,44 @@ func (cfg *Config) NewPackage(pkgPath, pkgName, workDir string, index clang.Inde return } - fset := token.NewFileSet() - imp := packages.NewImporter(fset, workDir) - - deps := cfg.Deps - if len(deps) > 0 { - c := cache.New(pkgHash) - c.Prepare(workDir, deps...) - imp.SetCache(c) - } - stdlibDirs := cfg.StdlibDirs(workDir) if debugSettings { log.Println("==> stdlibDirs:", stdlibDirs) } - incDirs, pkgPaths := mod.includeDirs(deps, 1, 1+len(stdlibDirs)) + const ( + stdlibPkgPath = "github.com/goplus/lib/c" + llarhubPrefix = "github.com/llarhub/" + ) + + nTotal := 1 + len(cfg.Deps) + len(stdlibDirs) + pkgPaths := make([]string, 1, nTotal) + incDirs := make([]string, 1, nTotal) + for _, dep := range cfg.Deps { + if !strings.Contains(dep, "/") { + dep = llarhubPrefix + dep + } + incDir, err := mod.IncludeDir(dep) + if err != nil { + log.Println("[WARN]", err) + continue + } + pkgPaths = append(pkgPaths, dep) + incDirs = append(incDirs, incDir) + } + nDeps := len(pkgPaths) for _, stdlibDir := range stdlibDirs { + pkgPaths = append(pkgPaths, stdlibPkgPath) incDirs = append(incDirs, stdlibDir) - pkgPaths = append(pkgPaths, "github.com/goplus/lib/c") } + fset := token.NewFileSet() + imp := packages.NewImporter(fset, workDir) + + c := cache.New(pkgHash) + c.Prepare(workDir, pkgPaths[1:nDeps+1]...) + imp.SetCache(c) + dir := cfg.Dir recursive := strings.HasSuffix(dir, "/...") if recursive { @@ -278,23 +295,6 @@ func (p Module) IncludeDir(modPath string) (includeDir string, err error) { return rootDir + includeSuffix, nil } -// includeDirs returns the include directories and package paths for the given dependencies. -// The reserved parameter specifies the number of reserved slots in the returned slices. -func (p Module) includeDirs(deps []string, n, reserved int) (incDirs, pkgPaths []string) { - incDirs = make([]string, n, len(deps)+reserved) - pkgPaths = make([]string, n, len(deps)+reserved) - for _, dep := range deps { - incDir, err := p.IncludeDir(dep) - if err != nil { - log.Println("[WARN]", err) - continue - } - incDirs = append(incDirs, incDir) - pkgPaths = append(pkgPaths, dep) - } - return -} - // ----------------------------------------------------------------------------- // ParseFlags constructs the command-line flags for parsing C/C++ source files with clang.