120 classes get their real base and real member types - #1379
Merged
Conversation
✅ PR validation — PassedCommitted merge introduces no reconstruction or attribution regression. Full merge validation
Per-file link-check detailAll 49 changed file(s) compile to the ROM byte-for-byte with correct relocation targets.
The private worker commits a test merge, builds the stock ROM profile, compares every executable module, measures matched and source-built code, checks contributor lineage, and verifies affected relocations. The mod profile is opt-in and is not part of this merge gate. |
andrewboudreau
force-pushed
the
cpp/subclass-migrations
branch
from
August 10, 2026 16:10
814c3e6 to
695ef88
Compare
andrewboudreau
force-pushed
the
cpp/subclass-migrations
branch
from
August 10, 2026 16:37
695ef88 to
fa6c85b
Compare
andrewboudreau
added a commit
that referenced
this pull request
Aug 10, 2026
The D0 half of #1379, split off so each PR clears the validator's 200-file cap. Stacked on #1379, which carries the class definitions these need. D0 is vtable slot 17 (or 1, for classes rooted below Actor): destroy, then return the object to the actor heap. Each of these was a hand-written .c file spelling out what the compiler emits anyway -- store the vtable, call the member destructors in reverse declaration order, chain to the base, call Memory::Deallocate. Declaring the class properly lets the compiler emit all of it, and the deallocation comes from the inline operator delete rather than anything in the file. Not in arm9: those D0s need an operator delete the arm9 classes do not have in scope, which is a separate problem and is not attempted here. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. Enrollment does not move: a D0 was already enrolled from its .c file, so the count stays while the source stops hand-spelling the mangled name. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x
This was referenced Aug 10, 2026
andrewboudreau
changed the base branch from
cpp/platform-enemy-layout
to
cpp/layout-headergen
August 10, 2026 16:38
andrewboudreau
force-pushed
the
cpp/layout-headergen
branch
from
August 10, 2026 17:17
4dc896e to
e849b5a
Compare
andrewboudreau
force-pushed
the
cpp/subclass-migrations
branch
from
August 10, 2026 17:17
4930609 to
59d996f
Compare
andrewboudreau
added a commit
that referenced
this pull request
Aug 10, 2026
The D0 half of #1379, split off so each PR clears the validator's 200-file cap. Stacked on #1379, which carries the class definitions these need. D0 is vtable slot 17 (or 1, for classes rooted below Actor): destroy, then return the object to the actor heap. Each of these was a hand-written .c file spelling out what the compiler emits anyway -- store the vtable, call the member destructors in reverse declaration order, chain to the base, call Memory::Deallocate. Declaring the class properly lets the compiler emit all of it, and the deallocation comes from the inline operator delete rather than anything in the file. Not in arm9: those D0s need an operator delete the arm9 classes do not have in scope, which is a separate problem and is not attempted here. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. Enrollment does not move: a D0 was already enrolled from its .c file, so the count stays while the source stops hand-spelling the mangled name. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x
andrewboudreau
force-pushed
the
cpp/subclass-migrations
branch
from
August 10, 2026 17:56
59d996f to
9cdf3f6
Compare
andrewboudreau
added a commit
that referenced
this pull request
Aug 10, 2026
The D0 half of #1379, split off so each PR clears the validator's 200-file cap. Stacked on #1379, which carries the class definitions these need. D0 is vtable slot 17 (or 1, for classes rooted below Actor): destroy, then return the object to the actor heap. Each of these was a hand-written .c file spelling out what the compiler emits anyway -- store the vtable, call the member destructors in reverse declaration order, chain to the base, call Memory::Deallocate. Declaring the class properly lets the compiler emit all of it, and the deallocation comes from the inline operator delete rather than anything in the file. Not in arm9: those D0s need an operator delete the arm9 classes do not have in scope, which is a separate problem and is not attempted here. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. Enrollment does not move: a D0 was already enrolled from its .c file, so the count stays while the source stops hand-spelling the mangled name. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x
The migration half of #1377, split from the layout work it rests on, with the D0 deleting destructors split off again on top so each PR clears the validator's 200-file cap. Stacked on #1378; the D0s are the PR above this one. 131 files. Hand-written .c destructors and methods become real C++ -- classes deriving from their actual base with typed members, in place of a flattened struct and a stand-in. Among them: DonutBlock as the worked example for the shadow-struct classes, thirty Platform subclasses unblocked by the 0x320 correction in #1378, and the array-member classes -- Wiggler's eight, Goomboss's three, ChainChomp's seven links, PathLift's Model[3], RotatingFirebar's one collision cylinder per flame. Six migrations that belong here by subject are in #1378 instead, because that half does not link without them: ChiefChilly, Unagi, Wiggler D0 and D1, Goomboss and ChainChomp all call the renamed Vector3 destructors. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. pr_linkcheck: no new WRONG or NO-REPRO. Enrollment does not move, and that is expected: a migration replaces the source of a function that was already enrolled, so the count stays while the source stops lying. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x
No content change. This PR's base moved from cpp/platform-enemy-layout to cpp/layout-headergen when the layout half was split in two, and the relay keys on head SHA -- retargeting alone does not re-submit, so the check still showed the 431-file count from the old base. This empty commit changes the head so the validator measures the 131 files this PR actually adds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x
andrewboudreau
force-pushed
the
cpp/subclass-migrations
branch
from
August 10, 2026 18:01
9cdf3f6 to
bf09e1e
Compare
andrewboudreau
added a commit
that referenced
this pull request
Aug 10, 2026
The D0 half of #1379, split off so each PR clears the validator's 200-file cap. Stacked on #1379, which carries the class definitions these need. D0 is vtable slot 17 (or 1, for classes rooted below Actor): destroy, then return the object to the actor heap. Each of these was a hand-written .c file spelling out what the compiler emits anyway -- store the vtable, call the member destructors in reverse declaration order, chain to the base, call Memory::Deallocate. Declaring the class properly lets the compiler emit all of it, and the deallocation comes from the inline operator delete rather than anything in the file. Not in arm9: those D0s need an operator delete the arm9 classes do not have in scope, which is a separate problem and is not attempted here. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. Enrollment does not move: a D0 was already enrolled from its .c file, so the count stays while the source stops hand-spelling the mangled name. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x
andrewboudreau
added a commit
that referenced
this pull request
Aug 10, 2026
* 59 classes get their real base and real member types The migration half of #1377, split from the layout work it rests on, with the D0 deleting destructors split off again on top so each PR clears the validator's 200-file cap. Stacked on #1378; the D0s are the PR above this one. 131 files. Hand-written .c destructors and methods become real C++ -- classes deriving from their actual base with typed members, in place of a flattened struct and a stand-in. Among them: DonutBlock as the worked example for the shadow-struct classes, thirty Platform subclasses unblocked by the 0x320 correction in #1378, and the array-member classes -- Wiggler's eight, Goomboss's three, ChainChomp's seven links, PathLift's Model[3], RotatingFirebar's one collision cylinder per flame. Six migrations that belong here by subject are in #1378 instead, because that half does not link without them: ChiefChilly, Unagi, Wiggler D0 and D1, Goomboss and ChainChomp all call the renamed Vector3 destructors. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. pr_linkcheck: no new WRONG or NO-REPRO. Enrollment does not move, and that is expected: a migration replaces the source of a function that was already enrolled, so the count stays while the source stops lying. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x * Re-request validation against the retargeted base No content change. This PR's base moved from cpp/platform-enemy-layout to cpp/layout-headergen when the layout half was split in two, and the relay keys on head SHA -- retargeting alone does not re-submit, so the check still showed the 431-file count from the old base. This empty commit changes the head so the validator measures the 131 files this PR actually adds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x * 61 deleting destructors become real C++ The D0 half of #1379, split off so each PR clears the validator's 200-file cap. Stacked on #1379, which carries the class definitions these need. D0 is vtable slot 17 (or 1, for classes rooted below Actor): destroy, then return the object to the actor heap. Each of these was a hand-written .c file spelling out what the compiler emits anyway -- store the vtable, call the member destructors in reverse declaration order, chain to the base, call Memory::Deallocate. Declaring the class properly lets the compiler emit all of it, and the deallocation comes from the inline operator delete rather than anything in the file. Not in arm9: those D0s need an operator delete the arm9 classes do not have in scope, which is a separate problem and is not attempted here. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. Enrollment does not move: a D0 was already enrolled from its .c file, so the count stays while the source stops hand-spelling the mangled name. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
andrewboudreau
added a commit
that referenced
this pull request
Aug 10, 2026
* 59 classes get their real base and real member types The migration half of #1377, split from the layout work it rests on, with the D0 deleting destructors split off again on top so each PR clears the validator's 200-file cap. Stacked on #1378; the D0s are the PR above this one. 131 files. Hand-written .c destructors and methods become real C++ -- classes deriving from their actual base with typed members, in place of a flattened struct and a stand-in. Among them: DonutBlock as the worked example for the shadow-struct classes, thirty Platform subclasses unblocked by the 0x320 correction in #1378, and the array-member classes -- Wiggler's eight, Goomboss's three, ChainChomp's seven links, PathLift's Model[3], RotatingFirebar's one collision cylinder per flame. Six migrations that belong here by subject are in #1378 instead, because that half does not link without them: ChiefChilly, Unagi, Wiggler D0 and D1, Goomboss and ChainChomp all call the renamed Vector3 destructors. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. pr_linkcheck: no new WRONG or NO-REPRO. Enrollment does not move, and that is expected: a migration replaces the source of a function that was already enrolled, so the count stays while the source stops lying. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x * Re-request validation against the retargeted base No content change. This PR's base moved from cpp/platform-enemy-layout to cpp/layout-headergen when the layout half was split in two, and the relay keys on head SHA -- retargeting alone does not re-submit, so the check still showed the 431-file count from the old base. This empty commit changes the head so the validator measures the 131 files this PR actually adds. Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
andrewboudreau
added a commit
that referenced
this pull request
Aug 10, 2026
* 59 classes get their real base and real member types The migration half of #1377, split from the layout work it rests on, with the D0 deleting destructors split off again on top so each PR clears the validator's 200-file cap. Stacked on #1378; the D0s are the PR above this one. 131 files. Hand-written .c destructors and methods become real C++ -- classes deriving from their actual base with typed members, in place of a flattened struct and a stand-in. Among them: DonutBlock as the worked example for the shadow-struct classes, thirty Platform subclasses unblocked by the 0x320 correction in #1378, and the array-member classes -- Wiggler's eight, Goomboss's three, ChainChomp's seven links, PathLift's Model[3], RotatingFirebar's one collision cylinder per flame. Six migrations that belong here by subject are in #1378 instead, because that half does not link without them: ChiefChilly, Unagi, Wiggler D0 and D1, Goomboss and ChainChomp all call the renamed Vector3 destructors. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. pr_linkcheck: no new WRONG or NO-REPRO. Enrollment does not move, and that is expected: a migration replaces the source of a function that was already enrolled, so the count stays while the source stops lying. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x * Re-request validation against the retargeted base No content change. This PR's base moved from cpp/platform-enemy-layout to cpp/layout-headergen when the layout half was split in two, and the relay keys on head SHA -- retargeting alone does not re-submit, so the check still showed the 431-file count from the old base. This empty commit changes the head so the validator measures the 131 files this PR actually adds. Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x * 61 deleting destructors become real C++ The D0 half of #1379, split off so each PR clears the validator's 200-file cap. Stacked on #1379, which carries the class definitions these need. D0 is vtable slot 17 (or 1, for classes rooted below Actor): destroy, then return the object to the actor heap. Each of these was a hand-written .c file spelling out what the compiler emits anyway -- store the vtable, call the member destructors in reverse declaration order, chain to the base, call Memory::Deallocate. Declaring the class properly lets the compiler emit all of it, and the deallocation comes from the inline operator delete rather than anything in the file. Not in arm9: those D0s need an operator delete the arm9 classes do not have in scope, which is a separate problem and is not attempted here. VERIFIED rombuild -j16, full ROM: 106/106 exact, 0 mismatching, 10,813 source-built, 87.88%. eligible.py differs from main only by the rename pair #1378 introduces. tools suite 265 passed. langmode ratchet PASS. No duplicate stems. Enrollment does not move: a D0 was already enrolled from its .c file, so the count stays while the source stops hand-spelling the mangled name. Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch. Claude-Session: https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The migration half of #1377, split from the layout work it rests on. Stacked on #1378 — merging that first makes this diff the migrations alone.
253 files on top of #1378's 310. Together the two reconstruct #1377's tree exactly (same git tree hash), so the split dropped nothing.
What this is
120 hand-written
.cdestructors and methods become real C++ — classes deriving from their actual base with typed members, in place of a flattened struct and a stand-in. Among them:0x320correction in Platform and Enemy get their real shape, and the type work 120 migrations rest on #1378Model[3], RotatingFirebar's one collision cylinder per flameSix migrations are in #1378 instead
ChiefChilly,Unagi,WigglerD0 and D1,GoombossandChainChompbelong here by subject but live in the layout PR, because that half does not link without them — they call the renamedVector3destructors. Splitting them out would have left #1378 red.Verified
rombuild.py -j16, full ROMeligible.pytools/suiteEnrollment does not move, and that is expected: a migration replaces the source of a function that was already enrolled, so the count stays while the source stops lying. The gain is in
langmode_audit's shadow-declaration counts, not insource-built.Original work is by the author of #1377; this split preserves the content, not the 37-commit history, which remains on that branch.
🤖 Generated with Claude Code
https://claude.ai/code/session_015AXm5k53WFPjCYcDHRDX3x