Skip to content

[cling] Always add primary NamespaceDecl to fNSSet - #23024

Open
jase231 wants to merge 1 commit into
root-project:masterfrom
jase231:jserwe_register_prim_ns
Open

[cling] Always add primary NamespaceDecl to fNSSet#23024
jase231 wants to merge 1 commit into
root-project:masterfrom
jase231:jserwe_register_prim_ns

Conversation

@jase231

@jase231 jase231 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

This Pull request:

Marks the primary NamespaceDecl as having external visible storage, ie. so that clang will query ROOT for any name it can't find in that namespace, and adds it into the fNSFromRootmaps/fNSSet alongside any potential non-primary redeclared context, so ROOT correctly reports any rootmap-redeclared namespace as an autoload candidate, even when the primary declaration comes from the PCH.

From the clang manual: Clang Internals Manual

Example:

  1. ROOT is built with gminimal=ON and without runtime modules. That build's PCH does not declare e.g. ROOT::RDataFrame, but it does declare the ROOT:: namespace. That NamespaceDecl in the PCH is designated the primary, and since it is sourced directly from the PCH it will never be inserted into fNSFromRootmaps.
  2. Then, dataframe components are installed, e.g. via wheel. These components can be autoparsed and their .rootmap(s) redeclare the ROOT:: namespace, which contains e.g. ROOT::RDataFrame. The NamespaceDecl representing this redeclaration is added to fNSFromRootmaps.
  3. The user tries to access ROOT::RDataFrame, clang's lookupImpl tries to find the external decl but does so by querying TCling with the primary NamespaceDecl for the ROOT:: namespace. TCling (through a chain of calls) checks for the primary in fNSFromRootmaps, but fails, because only dataframe's NamespaceDecl is in the set.
  4. TCling reports failure, and the user sees error: no member named 'RDataFrame' in namespace 'ROOT' even though RDataFrame is present and could have been autoparsed.

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

Bug discovered by LLM

When a namespace is multiply-defined, clang designates one as the primary. When it queries ROOT for external decls, it always passes the primary context, so fNSFromRootmaps is queried with the primary. This change adds the primary into the set alongside any potential non-primary redeclared context, so ROOT correctly reports that namespace as an autoload candidate.
@jase231
jase231 requested review from dpiparo and pcanal as code owners August 5, 2026 12:16
fNSSet.insert(nsDecl);

// When cling eventually queries fNSSet/fNSFromRootmaps, it always does so
// using the primary DeclContext. Therefore we need to store

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to record both?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in, "why do we need to record both rather than only recording the primary"? I don't think we do; if you think so too I will change to always recording the primary. I kept both because I didn't want to potentially break anything by dropping the non-primary in case that was used elsewhere, but I haven't found any other such case. I'll investigate the test failures this week. I'll also try to reproduce the original issue in a standard ROOT build, since I initially ran into this issue while working on wheels.

Also, based on getPrimaryContext's definition I think the return should always be non-null i.e. I can just cast, if you agree.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Test Results

    22 files      22 suites   3d 4h 3m 44s ⏱️
 3 834 tests  3 785 ✅ 0 💤  49 ❌
67 803 runs  67 678 ✅ 0 💤 125 ❌

For more details on these failures, see this check.

Results for commit cba31ae.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants