Skip to content

Update ROOT and Cling to LLVM22#21658

Merged
dpiparo merged 32 commits into
root-project:masterfrom
devajithvs:ROOT-llvm22
Jul 21, 2026
Merged

Update ROOT and Cling to LLVM22#21658
dpiparo merged 32 commits into
root-project:masterfrom
devajithvs:ROOT-llvm22

Conversation

@devajithvs

@devajithvs devajithvs commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

This Pull request:

We need LLVM22 support for the following before we can merge this:

  • CLAD
  • CppInterOp
  • AdaptiveCpp (Full LLVM22 support doesn't exist upstream yet, disable this now to not block the upgrade).

TODO:

  • Fix failing tests.
  • Squash and reorganize commits.
  • Separate PR for changes that can go independent of the upgrade.
  • Fix FIXME and temporary commits

Changes or fixes:

Checklist:

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

This PR fixes #

@devajithvs devajithvs self-assigned this Mar 23, 2026
@devajithvs devajithvs added skip code analysis Skip the code analysis CI steps for this PR, including verifying clang-formatting and running Ruff. clean build Ask CI to do non-incremental build on PR labels Mar 23, 2026
@devajithvs
devajithvs force-pushed the ROOT-llvm22 branch 2 times, most recently from 255c7e6 to cfd796b Compare March 23, 2026 13:19
@github-actions

github-actions Bot commented Mar 23, 2026

Copy link
Copy Markdown

Test Results

    23 files      23 suites   3d 15h 59m 43s ⏱️
 3 866 tests  3 866 ✅ 0 💤 0 ❌
75 299 runs  75 299 ✅ 0 💤 0 ❌

Results for commit 3587115.

♻️ This comment has been updated with latest results.

@ferdymercury

Copy link
Copy Markdown
Collaborator
  • AdaptiveCpp - potentially

Related: AdaptiveCpp/AdaptiveCpp#1986

@mcbarton

Copy link
Copy Markdown

Here is the PR I have updating CppInterOp to llvm 22 compiler-research/CppInterOp#812 . It builds with llvm 22 (tested through the ci with upstream llvm 22 and clang-repl), but several tests currently fail. Unsure how the patch would fair with roots llvm 22 and cling.

@devajithvs
devajithvs force-pushed the ROOT-llvm22 branch 2 times, most recently from 7738727 to d68c1c7 Compare March 24, 2026 09:28
@devajithvs
devajithvs force-pushed the ROOT-llvm22 branch 2 times, most recently from 7640bdc to 8920b0a Compare March 31, 2026 14:12
@devajithvs
devajithvs force-pushed the ROOT-llvm22 branch 2 times, most recently from 88b794b to 6284651 Compare April 20, 2026 12:45
@devajithvs
devajithvs force-pushed the ROOT-llvm22 branch 2 times, most recently from 8d87ccb to 1aa5aae Compare May 4, 2026 07:44
@devajithvs
devajithvs force-pushed the ROOT-llvm22 branch 3 times, most recently from 69156a4 to 8f2e30f Compare June 15, 2026 16:29
@devajithvs
devajithvs force-pushed the ROOT-llvm22 branch 7 times, most recently from c7b7cf3 to 45543a0 Compare June 24, 2026 11:55
LLVM 22 changes the representation of nested name qualifications and
removes `ElaboratedType` from the AST.

Adapt to these changes.

Ref: llvm/llvm-project#147835
LLVM 22 changes the representation of nested name qualifications and
removes `ElaboratedType` from the AST.

Adapt to these changes.

Ref: llvm/llvm-project#147835
We need some changes in cling to make it not assert and fail during
build/test. We rely on these a lot and can't afford to assert at these
places.

Fixes were attempted upstream but later got fixed in a different way:
- llvm/llvm-project@1f9c54a
- llvm/llvm-project@720abd7

Also fix errors with UnaryTransformTypes.
Reproducer:
```
cling> namespace N { struct D {}; }
cling> __remove_extent(N::D)* x; x // asserts
```
…andling

Fix failing tests:
- pyunittests-bindings-pyroot-cppyy-cppyy-test-lowlevel
- pyunittests-bindings-pyroot-cppyy-cppyy-test-datatypes
This fixes dictionary generation for ROOT types such as
ROOT::Math::IParametricFunctionMultiDimTempl<double> (exposed as
IModelFunction via a typedef chain), where the missing prefix caused
incorrect class names in the generated dictionary.

This is needed after the nested name specifier changes in LLVM22.
Fix tests:
- pyunittests-bindings-pyroot-cppyy-cppyy-test-advancedcpp
- root-io-newstl-run
… in LLVM22

LLVM22 removed ElaboratedType from the Clang type system and moved
NestedNameSpecifier directly into RecordType.

In LLVM20, ElaboratedType::desugar() stripped the global qualifier,
and we get "Object" from "::Object".

In LLVM22 this ElaboratedType no longer exists, prefix is stored directly
causing RecordType nodes to retain the global namespace prefix.

We try to restore the previous partial-desugaring behavior by explicitly
detecting RecordType instances with a global NestedNameSpecifier and
reconstructing the underlying canonical declaration type.

Only the global namespace ("::") is stripped; user-defined namespaces
("std::", "NS::") are preserved.
ElaboratedType was completely removed in LLVM22

There is no equivalent equivalent way to replace it with.

getPrefix() was used as a drop-in replacement for the `ElaboratedType`
during the rebase, this was wrong and not really needed.

This caused types accessed via 'using namespace' to enter code paths
that were never taken in LLVM20.

Without this fix rootcling fails with:

```
Error in <CloseStreamerInfoROOTFile>: Cannot find enum ROOT::Math::Integration::Type.
```
Where ROOT::Math::Integration::Type is resolved from a using namespace
… types

This will fix macos failures when building dictionaries.

Ref: llvm/llvm-project@7c402b8
This will fix gtest-tree-ntuple-ntuple-type-name, cppyy-test-pythonization
that was failing prior to this commit.

We probably need to revisit this and find a better/generalized way to
handle all similar cases.
The Transform.C test was constructing a bare Transform::Config that
did not populate m_toReplace, so the basic_string<char> to std::string
substitution could not fire during partial desugaring, causing the test
to produce "std::pair<const std::basic_string<char>, int>" instead of the
expected "std::pair<const std::string, int>".

Mirror what TNormalizedCtxImpl does: look up std::string, take its
canonical type pointer as the key, and insert the typedef type as the
replacement value in m_toReplace.
Prior to LLVM22, GetNormalizedName would strip Class keyword from
nested template arguments as a side-effect of ElaboratedType
desugaring. This was accidental erasure of user-written syntax.

In LLVM22, ElaboratedType was removed and the keyword is stored directly on
TagType. The normalization code no longer strips it, so the output now
reflects what the user wrote:
Unmark xfail for test14_templated_return_type
…ePaths

CopyIncludePaths assumed that a framework entry always implies
`Group==Angled` and called `report_fatal_error` for any other group.

This changed after LLVM commit: llvm/llvm-project@515b4a4

Framework entries land in UserEntries with `IsFramework=true` and
`Group=frontend::System` and cling fails on macos with
"Invalid option set!"

Fix by also allowing `Group=frontend::System` for framework entries.

See compiler-research/CppInterOp#672 (comment)
LLVM22 introduced UnsubstitutedConstraintSatisfactionCache:
llvm/llvm-project@e9972de

This causes some stale results to persist across transactions
For example, evaluating is_default_constructible_v<Inner<int>> for an
incomplete Inner<int> caches the 'false' value here.
Completing Inner<int> in the next transaction will see the cached 'false'
instead of re-evaluating.

There is a TODO in clang to make this a private member, so this solution
is not ideal.

This might not be the right fix, clang and clang-repl also fails for the
below, maybe we should just update the test-case
`roottest-root-meta-ROOT-7462-Test` to prevent this condition (gcc14
and above).

Minimal reproducer:
```
template <typename T> struct X; // Forward declaration
template <typename T> struct S { S() requires std::is_default_constructible_v<T> = default;};
bool b = std::is_default_constructible_v<S<X<int>>>;
template <> struct X<int> {}; // Complete the definition of X<int>

S<X<int>> s; // Fails without this patch
```

In ROOT:
```
{
    gInterpreter->Declare(R"(
      #include <type_traits>
      template <typename T> struct X;
      template <typename T>
      struct S { S() requires std::is_default_constructible_v<T> = default;};
    )");

    gInterpreter->Declare("bool b = std::is_default_constructible_v<S<X<int>>>;");
    gInterpreter->Declare("template <> struct X<int> {};");
    bool ok = gInterpreter->Declare("S<X<int>> s;");

    printf("%s\n", ok ? "PASS" : "FAIL");
}
```
LLVM21 implements CWG2369 ("Ordering between constraints and substitution",
llvm/llvm-project@e04e140

This moves constraint checking before full template argument substitution.
Alias templates may be expanded eagerly during parameter type substitution,
causing hard diagnostics to be emitted for substitution failures that are
expected and handled by InstantiateTemplateWithDefaults().

Use SFINAETrap so that substitution failures are treated as silent
failures, matching the previous behaviour.

Fix the remaining failing `pyunittests` on macos:

- pyunittests-bindings-distrdf-backend-distrdf-unit-backend-dist
- pyunittests-bindings-distrdf-backend-distrdf-unit-backend-graph-caching
- pyunittests-bindings-pyroot-cppyy-cppyy-test-cpp11features
- pyunittests-bindings-pyroot-pythonizations-pyroot-roofit
- pyunittests-io-io-rfile-py
- pyunittests-tree-dataframe-dataframe-merge-results
- pyunittests-tree-ntuple-ntuple-py-basics
- pyunittests-tree-ntuple-ntuple-py-model
AdaptiveCpp does not support LLVM22 yet, there is a PR open,
still need some work to get this building with static LLVM,
adaptiveCpp is designed to be used as a clang plugin using
libLLVM.so, for now, disable this so that this does not
become a blocker for LLVM22 upgrade.
BuiltinInfo.getName now returns and std::string instead of an
llvm::StringRef.

Use std::string instead of llvm::StringRef for m_BuiltinNames set and
builtinNames.

Ref: llvm/llvm-project@cd269fee
Backport upstream patch that fixes windows builds for clad, remove this in the next clad release
Teach getFullyQualifiedType() to rebuild UsingType nodes instead of
desugaring them. This preserves the written alias while still fully
qualifying the underlying type, similar the existing TypedefType
handling.
LLVM removed `ARCMigrate`, do the same in ROOT.

This will get rid of the CMAKE warning when configuring ROOT.

```
CMake Deprecation Warning at interpreter/llvm-project/clang/CMakeLists.txt:456 (message):
  'CLANG_ENABLE_ARCMT' is deprecated as ARCMigrate has been removed from
  Clang.  Please use 'CLANG_ENABLE_OBJC_REWRITER' instead to enable or
  disable the Objective-C rewriter.
```

Ref: llvm/llvm-project@c4a01974

@hahnjo hahnjo left a comment

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.

Great work!

@dpiparo

dpiparo commented Jul 21, 2026

Copy link
Copy Markdown
Member

I cannot but reiterate the message above: great work.

@dpiparo
dpiparo merged commit f82906a into root-project:master Jul 21, 2026
62 of 63 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clean build Ask CI to do non-incremental build on PR skip code analysis Skip the code analysis CI steps for this PR, including verifying clang-formatting and running Ruff.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants