A -shared library's class is imported once, with the library's vtable - #391
Merged
Merged
Conversation
Two bugs in importing a class from a -shared library, found through the class import cycle whose -shared test was left disabled; neither needs a cycle. - A module whose export depends on a class of another module declares that class in its __decls too (a derived class's base), so an importer of a library holding both read it twice: "redefinition of symbol named 'Base..new'". A second declaration of an imported class already processed in this module is now skipped (ClassInfo::processingDeclaration tells it from the same declaration generated again). - The declaration printer wrote accessors after all methods. The importer builds the vtable in the order it reads the members, so with `get textContent()` written before `addText()` their slots were swapped and the importer's `addText` call ran the getter. Accessors are now printed where their functions sit among the methods. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 28, 2026
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.
This fixes two bugs in importing a class from a
-sharedlibrary. I found them through the class import cycle (reference-path/import_cycle_class), whose-sharedvariant was left unregistered in #381. Neither bug needs a cycle.1. The class was declared twice:
redefinition of symbol named 'Base..new'.A module whose export depends on a class of another module declares that class in its own
__declstoo. A derived class's base is the typical case, and that re-export is deliberate: a library holding only the derived module still has to describe the base. So an importer of a library holding both modules read the base twice.mlirGen(ClassLikeDeclaration)now skips a second, different declaration of an imported class that is already fully processed in this module. The newClassInfo::processingDeclarationseparates that case from the same declaration being generated again on a later pass.2. The importer built the class's vtable in a different order from the library.
MLIRDeclarationPrinter::print(ClassInfo)printed all methods, then all accessors. The importer builds the vtable in the order it reads the members. So withget textContent()written beforeaddText()in the source, the two slots were swapped, and the importer'sn.addText("a")ran the getter: nothing was pushed, and readingchildNodes[0]faulted. Each accessor half (getorset) is now printed where its function sits inclassType->methods, which is the order the library built its vtable in. An accessor with no entry in the method list is still printed after it, as before.Tests:
reference-path-import-cycle-classis now registered throughtslang_add_import_tests, so it runs static,-sharedand-jit -shared.shared-class-members/, all three tiers. A base class has an accessor before a method, and a setter between methods. A derived class in another module of the same library extends it. It hit both bugs before this change.Results:
MLIRGenTestsunit tests (which include the declaration printer) pass 144/144.Not changed: with
--export=all, a getter's local variables end up in__declsas@dllimportglobals in a.f_Node.get_textContentnamespace. The test runner doesn't pass that flag, and it's a separate issue.🤖 Generated with Claude Code