Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions cl/_testcpp/namespace/in.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace bar {
namespace detail {
unsigned f(int a);
void f();
}
}

namespace bar {
class base
{
public:
~base();
};

typedef char boolean;
}
23 changes: 23 additions & 0 deletions cl/_testcpp/namespace/out.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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() {
}

type Bar_boolean = c.Char
8 changes: 4 additions & 4 deletions cl/class.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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{
Expand All @@ -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)
})
}

Expand Down
30 changes: 18 additions & 12 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)
Expand Down Expand Up @@ -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 {
Expand All @@ -180,25 +176,35 @@ 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:
Comment thread
xushiwei marked this conversation as resolved.
loadTypedef(ctx, decl)
loadTypedef(ctx, decl, ns)
case lc.CursorEnumDecl:
// 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:
log.Panicln("compileDecl: unknown kind =", decl.Kind)
}
}

func loadNamespace(ctx *pkgCtx, scope *scopeCtx, namespace clang.Cursor, ns string) {
Comment thread
xushiwei marked this conversation as resolved.
ns = ns + clang.String(namespace) + "_"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Namespace prefix separator is non-injective; distinct C++ names can collide

ns = ns + clang.String(namespace) + "_" uses _, which is a legal identifier character in C++. Distinct source structures can flatten to the same Go name — e.g. namespace bar::detail_f with a member vs. bar::detail::f both map to bar_detail_f. Link targets stay correct (they use the true mangled name), so this is a build-time correctness/robustness concern rather than mis-linkage, but with SetRedeclarable(true) it may surface as a confusing duplicate declaration rather than a clear error. Consider a separator that can't appear in C++ identifiers, or detecting duplicate flattened names explicitly. At minimum, document the limitation.

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
Expand All @@ -225,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()
Expand Down
4 changes: 2 additions & 2 deletions cl/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading