From fa346ba5c3ac88cb613c2085bc2b3ad9b01d9a2f Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 16 Sep 2026 20:54:23 +0800 Subject: [PATCH 1/3] cl: loadNamespace --- cl/_testcpp/namespace/in.h | 14 ++++++++++++++ cl/_testcpp/namespace/out.go | 21 +++++++++++++++++++++ cl/class.go | 8 ++++---- cl/compile.go | 24 +++++++++++++++--------- cl/compile_test.go | 2 +- cl/func.go | 4 ++-- 6 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 cl/_testcpp/namespace/in.h create mode 100644 cl/_testcpp/namespace/out.go diff --git a/cl/_testcpp/namespace/in.h b/cl/_testcpp/namespace/in.h new file mode 100644 index 00000000..223f7a3b --- /dev/null +++ b/cl/_testcpp/namespace/in.h @@ -0,0 +1,14 @@ +namespace bar { + namespace detail { + unsigned f(int a); + void f(); + } +} + +namespace bar { + class base + { + public: + ~base(); + }; +} diff --git a/cl/_testcpp/namespace/out.go b/cl/_testcpp/namespace/out.go new file mode 100644 index 00000000..a339d58d --- /dev/null +++ b/cl/_testcpp/namespace/out.go @@ -0,0 +1,21 @@ +package foo + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +const XGoPackage = true + +//go:linkname Bar_detail_f__1 C._ZN3bar6detail1fEi +func Bar_detail_f__1(a c.Int) c.Uint + +//go:linkname Bar_detail_f__0 C._ZN3bar6detail1fEv +func Bar_detail_f__0() + +type Bar_base struct { +} + +// llgo:link (*Bar_base).XGo_Dtor C._ZN3bar4baseD1Ev +func (this *Bar_base) XGo_Dtor() { +} diff --git a/cl/class.go b/cl/class.go index f384bbc5..5d718f9c 100644 --- a/cl/class.go +++ b/cl/class.go @@ -42,8 +42,8 @@ type classCtx struct { inPublic bool } -func compileClass(ctx *pkgCtx, scope *classCtx, cls clang.Cursor) { - origName := clang.String(cls) +func compileClass(ctx *pkgCtx, scope *classCtx, cls clang.Cursor, ns string) { + origName := ns + clang.String(cls) if debugCompileDecl { log.Println("class", origName) } @@ -68,7 +68,7 @@ func compileClass(ctx *pkgCtx, scope *classCtx, cls clang.Cursor) { } } -func loadClass(ctx *pkgCtx, cls clang.Cursor, defaultInPublic bool) { +func loadClass(ctx *pkgCtx, cls clang.Cursor, ns string, defaultInPublic bool) { pkg := ctx.pkg pkgTypes := pkg.Types scope := &classCtx{ @@ -81,7 +81,7 @@ func loadClass(ctx *pkgCtx, cls clang.Cursor, defaultInPublic bool) { return clang.Continue }) ctx.compiles = append(ctx.compiles, func(ctx *pkgCtx) { - compileClass(ctx, scope, cls) + compileClass(ctx, scope, cls, ns) }) } diff --git a/cl/compile.go b/cl/compile.go index 1426b4b9..b84e0619 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -95,10 +95,6 @@ type Config struct { // ----------------------------------------------------------------------------- -const ( - headerGoFile = "llcppg.i.go" -) - // NewPackage loads a translation unit and generates a Go package with the given package // path, name and configuration. func NewPackage(pkgPath, pkgName string, conf *Config, tu clang.TranslationUnit, files ...string) (ret Package, err error) { @@ -114,7 +110,7 @@ func NewPackage(pkgPath, pkgName string, conf *Config, tu clang.TranslationUnit, NewBuiltin: nil, NodeInterpreter: interp, CanImplicitCast: nil, - DefaultGoFile: headerGoFile, + DefaultGoFile: "", } pkg := gogen.NewPackage(pkgPath, pkgName, confGox) pkg.SetRedeclarable(true) @@ -165,13 +161,13 @@ func loadFiles(ctx *pkgCtx) { return clang.Continue } } - loadDecl(ctx, scope, decl) + loadDecl(ctx, scope, decl, "") return clang.Continue }) scope.reorder() } -func loadDecl(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor) { +func loadDecl(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor, ns string) { /* if global { ctx.logFile(decl) if decl.IsImplicit || ctx.inDepPkg { @@ -180,10 +176,10 @@ func loadDecl(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor) { } */ switch decl.Kind { case lc.CursorFunctionDecl: - loadGlobalFunc(ctx, scope, decl) + loadGlobalFunc(ctx, scope, decl, ns) case lc.CursorClassDecl, lc.CursorStructDecl: defaultInPublic := decl.Kind == lc.CursorStructDecl - loadClass(ctx, decl, defaultInPublic) + loadClass(ctx, decl, ns, defaultInPublic) case lc.CursorCXXMethod, lc.CursorConstructor, lc.CursorDestructor: loadOutsideMethod(ctx, decl) case lc.CursorTypedefDecl: @@ -192,6 +188,8 @@ func loadDecl(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor) { // compileEnum(ctx, decl, global) case lc.CursorMacroDefinition: loadMacro(ctx, decl) + case lc.CursorNamespace: + loadNamespace(ctx, scope, decl, ns) case lc.CursorVarDecl: // compileVarDecl(ctx, decl, global) default: @@ -199,6 +197,14 @@ func loadDecl(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor) { } } +func loadNamespace(ctx *pkgCtx, scope *scopeCtx, namespace clang.Cursor, ns string) { + ns = ns + clang.String(namespace) + "_" + clang.VisitChildren(namespace, func(decl, parent clang.Cursor) clang.ChildVisitResult { + loadDecl(ctx, scope, decl, ns) + return clang.Continue + }) +} + func loadMacro(ctx *pkgCtx, decl clang.Cursor) { if decl.IsMacroFunctionLike() != 0 { return diff --git a/cl/compile_test.go b/cl/compile_test.go index a3e4c213..d15cc364 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -99,7 +99,7 @@ func TestC(t *testing.T) { } func TestCpp(t *testing.T) { - testFromDir(t, "", "./_testcpp", cl.LanguageCXX) + testFromDir(t, "namespace", "./_testcpp", cl.LanguageCXX) } func TestPreprocessor(t *testing.T) { diff --git a/cl/func.go b/cl/func.go index e749d690..97a05c27 100644 --- a/cl/func.go +++ b/cl/func.go @@ -29,8 +29,8 @@ import ( // ----------------------------------------------------------------------------- -func loadGlobalFunc(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor) { - name := clang.String(decl) +func loadGlobalFunc(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor, ns string) { + name := ns + clang.String(decl) obj := scope.addObject(name, decl) ctx.compiles = append(ctx.compiles, func(ctx *pkgCtx) { compileFuncOrMethod(ctx, decl, obj, nil) From 1709a7cc24e35dd749ff76b152b58de01db6d54d Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 16 Sep 2026 20:56:17 +0800 Subject: [PATCH 2/3] x --- cl/compile_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/compile_test.go b/cl/compile_test.go index d15cc364..a3e4c213 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -99,7 +99,7 @@ func TestC(t *testing.T) { } func TestCpp(t *testing.T) { - testFromDir(t, "namespace", "./_testcpp", cl.LanguageCXX) + testFromDir(t, "", "./_testcpp", cl.LanguageCXX) } func TestPreprocessor(t *testing.T) { From 78174f622b83bcb89cd5f912d862e02cf16c6fe5 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 16 Sep 2026 21:04:44 +0800 Subject: [PATCH 3/3] cl loadTypedef: support ns --- cl/_testcpp/namespace/in.h | 2 ++ cl/_testcpp/namespace/out.go | 2 ++ cl/compile.go | 6 +++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cl/_testcpp/namespace/in.h b/cl/_testcpp/namespace/in.h index 223f7a3b..0534d7a6 100644 --- a/cl/_testcpp/namespace/in.h +++ b/cl/_testcpp/namespace/in.h @@ -11,4 +11,6 @@ namespace bar { public: ~base(); }; + + typedef char boolean; } diff --git a/cl/_testcpp/namespace/out.go b/cl/_testcpp/namespace/out.go index a339d58d..02ecf355 100644 --- a/cl/_testcpp/namespace/out.go +++ b/cl/_testcpp/namespace/out.go @@ -19,3 +19,5 @@ type Bar_base struct { // llgo:link (*Bar_base).XGo_Dtor C._ZN3bar4baseD1Ev func (this *Bar_base) XGo_Dtor() { } + +type Bar_boolean = c.Char diff --git a/cl/compile.go b/cl/compile.go index b84e0619..f9d836e4 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -183,7 +183,7 @@ func loadDecl(ctx *pkgCtx, scope *scopeCtx, decl clang.Cursor, ns string) { case lc.CursorCXXMethod, lc.CursorConstructor, lc.CursorDestructor: loadOutsideMethod(ctx, decl) case lc.CursorTypedefDecl: - loadTypedef(ctx, decl) + loadTypedef(ctx, decl, ns) case lc.CursorEnumDecl: // compileEnum(ctx, decl, global) case lc.CursorMacroDefinition: @@ -231,9 +231,9 @@ func loadMacro(ctx *pkgCtx, decl clang.Cursor) { }) } -func loadTypedef(ctx *pkgCtx, decl clang.Cursor) { +func loadTypedef(ctx *pkgCtx, decl clang.Cursor, ns string) { ctx.compiles = append(ctx.compiles, func(ctx *pkgCtx) { - origName := clang.String(decl) + origName := ns + clang.String(decl) pkg := ctx.pkg pkgTypes := pkg.Types underlying := decl.TypedefDeclUnderlyingType()