cl: loadNamespace - #726
Conversation
There was a problem hiding this comment.
Review: C++ namespace support
This PR threads a namespace prefix (ns string) through the load phase so C++ namespaces are flattened into underscore-joined Go identifiers (e.g. bar::detail::f -> Bar_detail_f). The approach is clean and the golden fixture (in.h/out.go) correctly covers nested namespaces, overloaded functions with mangled //go:linkname targets, and a namespaced class with a destructor.
I verified the concerns raised across correctness, performance, security, and docs:
- Performance: no issues — the prefix is built once per namespace level and traversal stays linear.
- Security: no issues —
//go:linkname/llgo:linktargets always come from the trueclang.Mangling, never from the concatenated prefix, so a Go-name collision cannot silently mis-link a symbol.
Findings below are correctness/robustness and clarity items.
Additional findings
/workspace/llcppg/cl/compile_test.go:102: [P2] TestCpp now runs only the namespace fixture, skipping all other C++ tests: Changingselfrom""to"namespace"meansTestCpponly runs thenamespacefixture. PerTestFromDir(cl/cltest/cltest.go:70), a non-emptyselfilters to subdirectories whose path contains it, so the other 7 C++ fixtures (ctor_dtor,fields,inline,methods,overload_fn,overload_mthd,struct) are now silently skipped — reducing C++ regression coverage exactly when new codegen behavior is added. If this was a debugging leftover, restoresel = ""; if intentional, a comment would help.
| } | ||
|
|
||
| func loadNamespace(ctx *pkgCtx, scope *scopeCtx, namespace clang.Cursor, ns string) { | ||
| ns = ns + clang.String(namespace) + "_" |
There was a problem hiding this comment.
[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.
No description provided.