[clang][reflection] Keep namespace member walks clear of out-of-line class-member definitions - #306
Open
Cfretz244 wants to merge 1 commit into
Conversation
…definitions; add regression test A re-opened namespace block beginning with an out-of-line member definition (lexically in the namespace, semantically in the class -- Eigen's header layout) derailed members_of: the definition pattern was yielded as a namespace member (its reflection breaks downstream metafunctions for dependent signatures), and stepping from it followed the class's multi-decl-context chain, silently dropping every remaining member. isReflectableDecl now rejects such definitions (the entity is enumerable through its class), and findIterableMember steps through their LEXICAL context. Decls whose semantic context is a namespace (the legitimate getLastMultDCSemaDecl chain) are untouched.
This was referenced Jun 10, 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.
Fixes #303.
Two complementary changes to the namespace member walk in
ExprConstantMeta.cpp:isReflectableDecl: reject any decl whose semanticDeclContextis aCXXRecordDeclwhile its lexical context differs. An out-of-line definition of a class member is a pure redeclaration — the entity is enumerable through its class, never through the namespace it is lexically written in — and its redeclaration filter used to pass it (the definition is the first declaration in its own lexical context), yielding (for class templates) a dependent definition PATTERN whose reflection breaks downstream metafunctions (isa<> used on a null pointerin display/mangling).findIterableMember: when stepping FROM such a decl (the cross-block hop lands on*decls_begin()of a re-opened block unchecked), use its LEXICAL context as the iteration context, so the walk continues through the namespace block instead of departing into the class'sgetPrevMultDCDeclInSemaContextchain and silently dropping every remaining member. Decls whose semantic context is a NAMESPACE (the legitimategetLastMultDCSemaDeclmulti-context chain, e.g.void ns::f() {}defined at TU scope) are deliberately not rewritten.The regression test covers: interleaved out-of-line defs in a single block, re-opened blocks beginning with template and non-template out-of-line definitions, full member recovery across all blocks, no definition leaking in as a member, and no duplicate enumeration through the class's own walk.
Validation (Release+assertions, AArch64/macOS): minimized repro flips from one bogus member to the three real ones; against real Eigen 5.0.1 headers, a
members_of(^^Eigen)lift goes from crashing (or silently yielding 69 of 125 members) to clean;clang/test/Reflection15/16, identical to pristine base.