Panel cxx-ada-spec

C++ to Ada specification feature panel

This panel turns exploratory g++ -fdump-ada-spec observations into repeatable evidence. It separates three outcomes that need different treatment: Driver options: -fdump-ada-spec, -fdump-ada-spec-slim. Compilers: 13.2.0, 14.2.0, 15.3.0, 16.2.0.

45 features

63 atomic cases

16 pairwise cases

32 grammar cases

22 runtime suites

States.

Verified working 15
Exercised end to end. The generated Ada compiles and behaves as the C++ does.
Fixed by a shipped bundle 21
A mapper defect with a bundle in the published patchset.
Fixed by a staged bundle 7
A mapper defect whose bundle is held out of the published patchset.
Bounded, not a defect 2
A boundary rather than a defect: Ada cannot represent the construct directly, or the mapper does not emit it.

Class.

2 features
FeatureStateEvidence
constructors-destructors Verified working panels/cxx-ada-spec/cases/core-language
data-members-layout Verified working with a guard panels/cxx-ada-spec/cases/core-language

Generated bindings expose layout. Compare Object_Size with compiler-produced sizeof values because Itanium mangling does not encode member layout.

Data layout.

4 features
FeatureStateEvidence
inherited-tail-padding-layout Staged cxx-ada-inherited-tail-padding

The staged bundle preserves the base subobject data size separately from its complete-object size and emits exact component positions for C++ tail-padding reuse. The nested primary-base component it selects is emitted by the staged virtual-base layout path, so patchset 1.2.0 does not ship it.

empty-class-object-size Staged cxx-ada-empty-class-storage

The staged bundle separates a zero-size empty value from its nonzero complete-object allocation. It omits artificial empty bases and only a no_unique_address selector that actually overlaps another field; naming that omitted C++ subobject requires an accessor wrapper. It reuses the staged tail-padding machinery, so patchset 1.2.0 does not ship it.

enums-bitfields-unions Verified runtime panels/cxx-ada-spec/cases/abi-layout panels/cxx-ada-spec/cases/call-abi panels/cxx-ada-spec/generated/catalog.py

Named enums, bit-fields, and unions compile; their size, alignment, and by-value runtime behavior are checked.

explicit-alignment Fixed by a bundle cxx-ada-explicit-alignment

Patchset 1.2.0 emits the user-specified alignment independently of packed layout.

Dispatch.

2 features
FeatureStateEvidence
virtual-methods Verified working panels/cxx-ada-spec/cases/core-language
derived-class-new-virtual-slots Staged cxx-ada-derived-virtual-slots

The staged bundle gives complete and deleting destructors hierarchy-stable Ada names so they override their inherited slots. Virtuals introduced later in a derived class then retain the C++ vtable indices, including through recursively nested concrete secondary bases. Patchset 1.2.0 does not ship this.

Function.

6 features
FeatureStateEvidence
overloaded-methods Verified working panels/cxx-ada-spec/cases/core-language
static-methods Verified working panels/cxx-ada-spec/cases/core-language
operators-conversions Verified ada compile panels/cxx-ada-spec/generated/catalog.pyoperatorsconversion_operators
method-cv-overloads Fixed by a bundle cxx-ada-qualified-method-names
method-ref-qualifier-overloads Fixed by a bundle cxx-ada-qualified-method-names
copy-move-special-members Fixed by a bundle cxx-ada-qualified-method-names

Patchset 1.2.0 gives move assignment a distinct Ada name.

Inheritance.

5 features
FeatureStateEvidence
single-inheritance Verified working panels/cxx-ada-spec/cases/core-language

The positive case avoids inherited tail-padding reuse and checks both Ada and C++ object sizes.

multiple-inheritance-interface-secondary Verified working panels/cxx-ada-spec/cases/interface-secondary-base

The dumper maps a pure abstract, data-free secondary base to a limited interface; the runtime test verifies Ada dispatch and secondary-base pointer adjustment.

multiple-inheritance-concrete-secondary Staged with access view panels/cxx-ada-spec/generated/catalog.pyconcrete_multiple_inheritance cxx-ada-concrete-multiple-inheritance cxx-ada-virtual-diamond-layout panels/cxx-ada-spec/cases/recursive-secondary-base

The staged bundle maps the C++ primary base to Ada inheritance and each additional concrete base to exact nested as-base storage. Access-view conversions at nested component addresses support secondary virtual dispatch, including a secondary base that itself has concrete primary and secondary bases; dynamic virtual-base conversions remain an ABI boundary. Patchset 1.2.0 does not ship this; an unstaged compiler still omits every secondary base subobject.

virtual-inheritance-layout Staged cxx-ada-virtual-inheritance-layout

The staged bundle preserves complete size, alignment, direct-member position, and virtual-base position while leaving the hidden ABI pointer as an opaque gap. Patchset 1.2.0 does not ship this.

virtual-diamond-as-base-layout Staged cxx-ada-virtual-diamond-layout

The staged bundle emits shortened storage types for non-polymorphic direct bases that omit their shared virtual base, preserving all visible diamond fields without duplicating the root. Patchset 1.2.0 does not ship this.

Library.

1 features
FeatureStateEvidence
standard-library-nontrivial-values Facade required panels/cxx-ada-spec/cases/stdlib-value-facade

A slim std::string-by-value dump references missing transitive Ada units. The executable case keeps std::string ownership in C++ and crosses a C-compatible data-and-length facade instead.

Name lookup.

7 features
FeatureStateEvidence
namespace-collisions Fixed by a bundle cxx-ada-namespace-identity

Patchset 1.2.0 preserves complete named namespace paths in generated Ada identifiers.

enclosing-type-method-name-collisions Fixed by a bundle cxx-ada-enclosing-type-method-names

Patchset 1.2.0 gives only a method that collides case-insensitively with its enclosing type a stable Method suffix while retaining the C++ external symbol.

profile-formal-type-name-collisions Fixed by a bundle cxx-ada-profile-formal-type-names

Patchset 1.2.0 prefixes a formal when its Ada identifier would hide its own type, a later formal's type, or the result type.

visible-type-method-name-collisions Fixed by a bundle cxx-ada-visible-type-method-names

Patchset 1.2.0 gives a method a stable Method suffix when its identifier collides with a type made visible from another generated class package.

nested-classes-anonymous-scopes Verified ada compile panels/cxx-ada-spec/generated/catalog.pynested_classanonymous_namespacenested_namespace
ada-casefold-collisions Fixed by a bundle cxx-ada-casefold-identity

Patchset 1.2.0 assigns stable scope-local suffixes to later case variants and all of their references.

generated-name-collisions Staged cxx-ada-generated-name-identity

The staged bundle reserves source spellings and gives only colliding synthesized declarations readable scope-local suffixes. It renames entities the staged ABI-layout bundles introduce and does not apply without them, so patchset 1.2.0 does not ship it.

Runtime.

2 features
FeatureStateEvidence
exceptions Verified runtime interoperability panels/cxx-ada-spec/generated/catalog.pyexception_throw panels/cxx-ada-spec/cases/exception-interoperability

A C++ throw propagates into an Ada others handler at both optimization levels. A status-returning C facade is also verified for APIs that choose not to expose exceptions. GNAT's internal foreign-language identity API is version-dependent and is not part of this portable claim.

scalar-call-abi Verified with target boundary panels/cxx-ada-spec/cases/call-abi

Boolean, signed-char, unsigned-long-long, float, and double mappings execute at both optimization levels. Long double also executes and must match except on Linux AArch64 toolchains where GNAT and C++ use incompatible target calling conventions; that explicit boundary does not suppress the remaining ABI oracles.

Template.

8 features
FeatureStateEvidence
explicit-template-instantiations Verified working cxx-ada-template-qualification
external-template-instance-references Fixed by a bundle cxx-ada-template-qualification

Aliases, fields, parameters, and results need the generated instance-package qualifier.

trivial-template-record-syntax Fixed by a bundle cxx-ada-template-record-termination

Patchset 1.2.0 terminates the Convention aspect for trivial records emitted in concrete template packages.

uninstantiated-templates Not emitted panels/cxx-ada-spec/cases/uninstantiated-templates

The dumper emits no declaration until the C++ template is explicitly instantiated; the executable case proves that the explicit instance is then emitted and usable.

class-template-specializations Fixed by a bundle panels/cxx-ada-spec/generated/catalog.pypartial_specializationfull_specialization

Patchset 1.2.0 terminates the generated trivial records.

advanced-template-parameters Fixed by a bundle cxx-ada-template-nested-types

Patchset 1.2.0 declares anonymous array field types inside concrete packages with non-type or defaulted template arguments.

template-template-parameters Fixed by a bundle panels/cxx-ada-spec/generated/catalog.pytemplate_template_parameter

Patchset 1.2.0 terminates the generated trivial record.

nested-alias-constrained-templates Fixed by a bundle panels/cxx-ada-spec/generated/catalog.pynested_templatealias_templateconstrained_template

Patchset 1.2.0 terminates trivial records and maps alias-template instances to the concrete type in their generated packages.

Type system.

8 features
FeatureStateEvidence
references-rvalue-references Verified ada compile panels/cxx-ada-spec/generated/catalog.pyfree_rvalue_references cxx-ada-qualified-method-names

Patchset 1.2.0 preserves lvalue- and rvalue-qualified method identity in stable Ada suffixes.

cv-qualifiers-noexcept Verified ada compile cxx-ada-qualified-method-names panels/cxx-ada-spec/generated/catalog.pynoexcept_default_arguments

Patchset 1.2.0 preserves cv-qualified method identity in stable Ada suffixes; noexcept/default arguments compile.

data-member-pointers Fixed by a bundle cxx-ada-member-pointers

Patchset 1.2.0 preserves the Itanium ABI ptrdiff_t offset, including its -1 null representation; dereferencing remains a C++ operation.

member-function-pointers Fixed by a bundle cxx-ada-member-pointers

Patchset 1.2.0 preserves the opaque two-word Itanium ABI representation, including nonvirtual, virtual, and null values; invocation remains a C++ operation.

extended-character-types Fixed by a bundle cxx-ada-char8-type

Patchset 1.2.0 maps C++20 char8_t to ABI-equivalent Interfaces.C.unsigned_char; wchar_t, char16_t, and char32_t retain their existing mappings.

complex-vector-types Patched with method wrapper boundary cxx-ada-vector-types panels/cxx-ada-spec/generated/catalog.pycomplex_and_vector

Complex float types already mapped to Ada.Numerics complex units. Patchset 1.2.0 replaces vector placeholders with aligned GNAT machine-vector arrays. Free and C-wrapper profiles use the direct vector calling convention; direct Ada dispatch to a vector-bearing C++ method is not portable across the tested compiler/target matrix.

anonymous-enum-constants Fixed by a bundle cxx-ada-anonymous-enums

Patchset 1.2.0 emits sequential enumerations or integer-subtype constants and maps signature references consistently to the synthetic type.

integer-128 Fixed by a bundle cxx-ada-int128-types

Patchset 1.2.0 backports GCC 15's prefix recognition to GCC 13 and 14; GCC 15 and 16 are known-good controls.

Runtime suites.

Each suite links C++ and Ada and runs at -O0 and -O2.

Method.

How the panel is built, and what it deliberately bounds The panel's own notes: probe layers, run states, target boundaries, and the limits it records rather than hides.

This panel turns exploratory g++ -fdump-ada-spec observations into repeatable evidence. It separates three outcomes that need different treatment:

  • a supported mapping, which gets a positive end-to-end C++/Ada case;
  • a mapper defect, which gets an independent patch bundle with an executable before/after regression;
  • a C++ construct Ada cannot represent directly, which is documented as a facade boundary rather than disguised as a mapper bug.

matrix.toml records feature-level conclusions. coverage.toml assigns every atomic probe to a feature group, lists the runtime oracles, and states the remaining limits. generated/coverage.py fails if a catalog probe is omitted or assigned twice.

The panel runs in three states. unpatched characterizes the pinned upstream compiler. patched is a compiler carrying exactly patchset 1.2.0, which is what a release ships. staged additionally carries the staged bundles listed under staged subjects. A patched run makes no claim about a staged subject: it reports those suites as skipped rather than asserting either the defect or the fix.

The executable panel currently has four layers:

  • 63 isolated atomic probes cover types and layout, pointers and functions, templates, inheritance, names and linkage, and runtime/storage declarations. Each probe runs in its own directory, so one malformed dump cannot mask a later feature. Required declarations are checked before the generated Ada is compiled. Versioned expectation files distinguish successful mappings from repeatable invalid Ada and omissions.
  • 16 generated cases cover all 88 value pairs across payload kind, reference carrier, C++ scope, qualifier, and full/slim dump mode. This is pairwise interaction coverage, not a hand-selected sample.
  • 32 fixed-seed grammar cases combine three to seven declarations per translation unit, with periodic inheritance and overload clusters. They exercise higher-order interactions in the currently representable subset and alternate full and slim dump modes.
  • Twenty-two shipped runtime suites, plus eight staged ones, link C++ and Ada at -O0 and -O2. They check scalar, enum, record, union, pointer, reference, and callback calling conventions; object size, alignment, and field offsets; ordinary, interface, and concrete secondary-base virtual dispatch, including recursively nested concrete bases; template qualification, record termination, nested types, explicit alignment, namespace and method identity—including enclosing-type, use-visible type/method, and subprogram-profile collisions—anonymous enumeration values, and char8_t, 128-bit integers, machine vectors through a C++ method wrapper, and opaque pointer-to-member values; uninstantiated-template emission, a nontrivial standard-library value facade, C++ exception propagation into an Ada handler; and the exact behavior of known defects.

The call-ABI suite reports the long double result separately. On Linux AArch64 with the pinned GCC 13--15 toolchains, GNAT and C++ disagree on that target calling convention even though the mapper emits the standard Interfaces.C.long_double declaration. That target/runtime boundary is reported explicitly instead of stopping the suite, so enum, record, union, pointer, reference, and callback oracles still execute. A mismatch on any other target remains a failure.

The defect regressions reproduce malformed template records before patching, anonymous nested template types before patching, anonymous enum omissions before patching, pointer-to-member syntax failures, standalone empty-class storage drift, inherited tail-padding drift, explicit alignment before patching, virtual-inheritance, virtual-diamond, and concrete multiple-inheritance layout drift, unsigned 128-bit integer failures on GCC 13 and 14 before patching, and several version- or type-specific omissions. Independent problems must become independent patch bundles.

The coverage summary reports all three baselines. Patchset 1.2.0 leaves one atomic case classified non-passing on every supported major: concrete_multiple_inheritance, whose subject is staged. A staged compiler passes all 63.

That atomic case does not merely require legal Ada. Dropping both base subobjects also compiles, so the case requires the primary base as Ada inheritance and the secondary base as its own storage view; a compiler without the staged bundle reports spec-mismatch, not a false pass.

Its C++ classes declare virtual destructors deliberately. Without one the mapper emits no base list at all, so both base subobjects vanish from the Ada record even with the staged layout bundles applied. That is a distinct gap from the one this probe characterizes and is recorded under coverage.toml limits; it has no bundle yet.

The confirmed-history ledger is larger than that residual atomic count: twenty-two independent C++ mapper defects have bundles introduced for 1.2.0 — fifteen accepted into the patchset and seven staged — and no confirmed fixed-layout runtime defect remains. Every linked bundle, accepted or staged, contains the offending C++, the unpatched Ada output, the corrected Ada output, and an executable -O0/-O2 before/after regression:

Staged subjects

Patchset 1.2.0 does not ship these. They carry the same evidence as an accepted bundle and run in the panel's staged state; a patched run skips them and their eight runtime suites.

The following list is only the work still open or intentionally bounded, not the complete defect history.

The remaining confirmed inventory is deliberately explicit:

  • tested semantic boundaries rather than hidden mapper successes: uninstantiated templates are not emitted, nontrivial standard-library values require a facade, and dynamic virtual-base conversions remain ABI operations. C++ exception propagation is tested and supported through Ada's portable others handler. GNAT's internal API for recovering the foreign language identity varies by runtime version and is not claimed as portable behavior; Linux AArch64 long double interoperability on affected GNAT releases is a compiler call-ABI boundary, not a mapper-spelling success. Direct Ada dispatch to vector-bearing C++ methods likewise requires a C++ wrapper, because tested GNAT versions do not classify that method ABI consistently.

Run the complete current panel against a compiler root:

./panels/cxx-ada-spec/run-panel.sh TOOLCHAIN_ROOT GCC_VERSION unpatched

Use patched after applying patchset 1.2.0, and staged after additionally applying the staged bundles with scripts/apply-staged.sh. An expected pre-patch compiler rejection counts as a passing defect characterization; a patched or staged run must generate compilable Ada and execute its consumer for every subject that state covers.

The matrix is deliberately broader than the current patchset. New confirmed defects must become independent bundles/<id>/ entries instead of being folded into the template-qualification patch. The panel is operationally broad but not mathematically exhaustive; coverage.toml explicitly lists constructs still requiring probes or runtime ABI oracles.