From a604b33d10a633b9b06051000b64d02076dc362c Mon Sep 17 00:00:00 2001
From: Eleni Mathioulaki <emathioulaki@athenarc.gr>
Date: Thu, 13 Apr 2023 19:33:01 +0000
Subject: [PATCH] update llvm from Spack upstream

---
 packages/llvm/D133513.diff                   |  29 +
 packages/llvm/constexpr_longdouble.patch     |  21 +-
 packages/llvm/constexpr_longdouble_9.0.patch |  44 +-
 packages/llvm/libomp-libflags-as-list.patch  |  14 +
 packages/llvm/llvm12-thread.patch            |  31 +
 packages/llvm/llvm13-14-thread.patch         |  19 +
 packages/llvm/llvm13-fujitsu.patch           |  15 +
 packages/llvm/llvm14-hwloc-ompd.patch        |  13 +
 packages/llvm/llvm15-thread.patch            |  23 +
 packages/llvm/package.py                     | 678 ++++++++++---------
 10 files changed, 570 insertions(+), 317 deletions(-)
 create mode 100644 packages/llvm/D133513.diff
 create mode 100644 packages/llvm/libomp-libflags-as-list.patch
 create mode 100644 packages/llvm/llvm12-thread.patch
 create mode 100644 packages/llvm/llvm13-14-thread.patch
 create mode 100644 packages/llvm/llvm13-fujitsu.patch
 create mode 100644 packages/llvm/llvm14-hwloc-ompd.patch
 create mode 100644 packages/llvm/llvm15-thread.patch

diff --git a/packages/llvm/D133513.diff b/packages/llvm/D133513.diff
new file mode 100644
index 00000000..54849b8e
--- /dev/null
+++ b/packages/llvm/D133513.diff
@@ -0,0 +1,29 @@
+Index: lldb/bindings/python/get-python-config.py
+===================================================================
+--- lldb/bindings/python/get-python-config.py
++++ lldb/bindings/python/get-python-config.py
+@@ -44,15 +44,21 @@
+     elif args.variable_name == "LLDB_PYTHON_EXE_RELATIVE_PATH":
+         tried = list()
+         exe = sys.executable
+-        prefix = os.path.realpath(sys.prefix)
++        prefix = sys.prefix
+         while True:
+             try:
+                 print(relpath_nodots(exe, prefix))
+                 break
+             except ValueError:
+                 tried.append(exe)
+-                if os.path.islink(exe):
+-                    exe = os.path.join(os.path.realpath(os.path.dirname(exe)), os.readlink(exe))
++                real_exe_dirname = os.path.realpath(os.path.dirname(exe))
++                real_prefix = os.path.realpath(prefix)
++                if prefix != real_prefix:
++                    prefix = real_prefix
++                    exe = os.path.join(real_exe_dirname, os.path.basename(exe))
++                    continue
++                elif os.path.islink(exe):
++                    exe = os.path.join(real_exe_dirname, os.readlink(exe))
+                     continue
+                 else:
+                     print("Could not find a relative path to sys.executable under sys.prefix", file=sys.stderr)
diff --git a/packages/llvm/constexpr_longdouble.patch b/packages/llvm/constexpr_longdouble.patch
index f825b142..8b90001d 100644
--- a/packages/llvm/constexpr_longdouble.patch
+++ b/packages/llvm/constexpr_longdouble.patch
@@ -1,14 +1,27 @@
+From 3bf63cf3b366d3a57cf5cbad4112a6abf6c0c3b1 Mon Sep 17 00:00:00 2001
+From: Marshall Clow <mclow.lists@gmail.com>
+Date: Tue, 2 Apr 2019 14:46:36 +0000
+Subject: [PATCH] Special case some duration arithmetic for GCC and PPC because
+ their long double constant folding is broken. Fixes PR#39696.
+
+llvm-svn: 357478
+---
+ libcxx/include/thread | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libcxx/include/thread b/libcxx/include/thread
+index df06ff70f8e37f22f4108be8e5e79a38052a11dd..400459ae7f32c4d7cd24b2d85c49d789500e432d 100644
 --- a/libcxx/include/thread
 +++ b/libcxx/include/thread
-@@ -435,7 +435,12 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)
+@@ -434,7 +434,12 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)
      using namespace chrono;
      if (__d > duration<_Rep, _Period>::zero())
      {
-+#if ! (defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__))
++#if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
 +    //  GCC's long double const folding is incomplete for IBM128 long doubles.
-         _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
-+#else
 +        _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ;
++#else
+         _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
 +#endif
          nanoseconds __ns;
          if (__d < _Max)
diff --git a/packages/llvm/constexpr_longdouble_9.0.patch b/packages/llvm/constexpr_longdouble_9.0.patch
index bbc5ab73..9a62f270 100644
--- a/packages/llvm/constexpr_longdouble_9.0.patch
+++ b/packages/llvm/constexpr_longdouble_9.0.patch
@@ -1,12 +1,38 @@
--- a/libcxx/include/thread
+From d9a42ec98adcb1ebc0c3837715df4e5a50c7ccc0 Mon Sep 17 00:00:00 2001
+From: "Joel E. Denny" <jdenny.ornl@gmail.com>
+Date: Wed, 10 Jun 2020 12:40:43 -0400
+Subject: [PATCH] [libc++] Work around gcc/Power9 bug in `include/thread`
+
+This fixes PR39696, which breaks the libcxx build with gcc (I tested
+7.5.0) on Power9.  This fix was suggested at
+
+https://bugs.llvm.org/show_bug.cgi?id=39696#c38
+
+but never applied.  It just reverts 0583d9ea8d5e, which reverses
+components of the original fix in 3bf63cf3b366, which is correct.
+
+Fixes https://llvm.org/PR39696
+
+Reviewed By: ldionne
+
+Differential Revision: https://reviews.llvm.org/D81438
+---
+ libcxx/include/thread | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libcxx/include/thread b/libcxx/include/thread
+index 22aa4f201295867cff57b7a944e6b7bd67b22ad3..6eff1800acdbef09eae4417eee977fa350c596ea 100644
+--- a/libcxx/include/thread
 +++ b/libcxx/include/thread
-@@ -370,7 +370,7 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)
-     using namespace chrono;
-     if (__d > duration<_Rep, _Period>::zero())
+@@ -365,9 +365,9 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)
      {
--#if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
-+#if ! (defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__))
+ #if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
      //  GCC's long double const folding is incomplete for IBM128 long doubles.
-         _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
- #else
-
+-        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
+-#else
+         _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ;
++#else
++        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
+ #endif
+         nanoseconds __ns;
+         if (__d < _Max)
diff --git a/packages/llvm/libomp-libflags-as-list.patch b/packages/llvm/libomp-libflags-as-list.patch
new file mode 100644
index 00000000..995f55a4
--- /dev/null
+++ b/packages/llvm/libomp-libflags-as-list.patch
@@ -0,0 +1,14 @@
+diff --git a/openmp/runtime/cmake/LibompHandleFlags.cmake b/openmp/runtime/cmake/LibompHandleFlags.cmake
+index 9e19e59ba17d..f92fa12d851a 100644
+--- a/openmp/runtime/cmake/LibompHandleFlags.cmake
++++ b/openmp/runtime/cmake/LibompHandleFlags.cmake
+@@ -144,7 +144,8 @@ function(libomp_get_libflags libflags)
+   endif()
+   set(libflags_local ${libflags_local} ${LIBOMP_LIBFLAGS})
+   libomp_setup_flags(libflags_local)
+-  set(${libflags} ${libflags_local} PARENT_SCOPE)
++  libomp_string_to_list("${libflags_local}" libflags_local_list)
++  set(${libflags} ${libflags_local_list} PARENT_SCOPE)
+ endfunction()
+
+ # Fortran flags
diff --git a/packages/llvm/llvm12-thread.patch b/packages/llvm/llvm12-thread.patch
new file mode 100644
index 00000000..bbe3c253
--- /dev/null
+++ b/packages/llvm/llvm12-thread.patch
@@ -0,0 +1,31 @@
+diff --git a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake b/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake
+index e3c2a580396e..5f76992d193e 100644
+--- a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake
++++ b/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake
+@@ -249,3 +249,6 @@ if (NOT LIBOMPTARGET_CUDA_TOOLKIT_ROOT_DIR_PRESET AND
+     endif()
+   endif()
+ endif()
++
++find_package(Threads REQUIRED)
++set(OPENMP_PTHREAD_LIB ${CMAKE_THREAD_LIBS_INIT})
+diff --git a/openmp/libomptarget/src/CMakeLists.txt b/openmp/libomptarget/src/CMakeLists.txt
+index 15e6c3bbaf1f..3e5a73504a08 100644
+--- a/openmp/libomptarget/src/CMakeLists.txt
++++ b/openmp/libomptarget/src/CMakeLists.txt
+@@ -30,6 +30,7 @@ if(OPENMP_STANDALONE_BUILD OR (NOT OPENMP_ENABLE_LIBOMPTARGET_PROFILING))
+   add_library(omptarget SHARED ${LIBOMPTARGET_SRC_FILES})
+   target_link_libraries(omptarget
+     ${CMAKE_DL_LIBS}
++    ${OPENMP_PTHREAD_LIB}
+     "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports")
+ else()
+   set(LLVM_LINK_COMPONENTS
+@@ -37,6 +38,7 @@ else()
+     )
+   add_llvm_library(omptarget SHARED ${LIBOMPTARGET_SRC_FILES}
+       LINK_LIBS ${CMAKE_DL_LIBS}
++      ${OPENMP_PTHREAD_LIB}
+       "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports"
+       )
+   target_compile_definitions(omptarget PUBLIC OMPTARGET_PROFILE_ENABLED)
diff --git a/packages/llvm/llvm13-14-thread.patch b/packages/llvm/llvm13-14-thread.patch
new file mode 100644
index 00000000..0067a930
--- /dev/null
+++ b/packages/llvm/llvm13-14-thread.patch
@@ -0,0 +1,19 @@
+--- spack-src/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake.org	2022-02-08 14:58:13.000000000 +0900
++++ spack-src/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake	2022-02-08 13:58:53.000000000 +0900
+@@ -276,4 +276,5 @@
+   endif()
+ endif()
+
+-set(OPENMP_PTHREAD_LIB ${LLVM_PTHREAD_LIB})
++find_package(Threads REQUIRED)
++set(OPENMP_PTHREAD_LIB ${CMAKE_THREAD_LIBS_INIT})
+--- spack-src/openmp/libomptarget/src/CMakeLists.txt.org	2022-02-09 08:49:35.000000000 +0900
++++ spack-src/openmp/libomptarget/src/CMakeLists.txt	2022-02-09 08:50:18.000000000 +0900
+@@ -36,6 +36,7 @@
+ endif()
+ target_link_libraries(omptarget PRIVATE
+   ${CMAKE_DL_LIBS}
++  ${OPENMP_PTHREAD_LIB}
+   "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports")
+ 
+ # Install libomptarget under the lib destination folder.
diff --git a/packages/llvm/llvm13-fujitsu.patch b/packages/llvm/llvm13-fujitsu.patch
new file mode 100644
index 00000000..aa215bcf
--- /dev/null
+++ b/packages/llvm/llvm13-fujitsu.patch
@@ -0,0 +1,15 @@
+--- spack-src/libcxx/include/__config.org	2022-02-03 14:36:11.000000000 +0900
++++ spack-src/libcxx/include/__config	2022-02-04 08:39:59.000000000 +0900
+@@ -52,7 +52,11 @@
+ #  elif __cplusplus <= 201703L
+ #    define _LIBCPP_STD_VER 17
+ #  elif __cplusplus <= 202002L
+-#    define _LIBCPP_STD_VER 20
++#    if defined(__FUJITSU) || defined(__CLANG_FUJITSU)
++#      define _LIBCPP_STD_VER 17
++#    else
++#      define _LIBCPP_STD_VER 20
++#    endif
+ #  else
+ #    define _LIBCPP_STD_VER 21  // current year, or date of c++2b ratification
+ #  endif
diff --git a/packages/llvm/llvm14-hwloc-ompd.patch b/packages/llvm/llvm14-hwloc-ompd.patch
new file mode 100644
index 00000000..bdae92e0
--- /dev/null
+++ b/packages/llvm/llvm14-hwloc-ompd.patch
@@ -0,0 +1,13 @@
+--- a/openmp/libompd/src/CMakeLists.txt
++++ b/openmp/libompd/src/CMakeLists.txt
+@@ -44,6 +44,10 @@
+         ${LIBOMP_SRC_DIR}
+ )
+
++if(${LIBOMP_USE_HWLOC})
++  include_directories(${LIBOMP_HWLOC_INSTALL_DIR}/include)
++endif()
++
+ INSTALL( TARGETS ompd
+         LIBRARY DESTINATION ${OPENMP_INSTALL_LIBDIR}
+         ARCHIVE DESTINATION ${OPENMP_INSTALL_LIBDIR}
diff --git a/packages/llvm/llvm15-thread.patch b/packages/llvm/llvm15-thread.patch
new file mode 100644
index 00000000..cffb5591
--- /dev/null
+++ b/packages/llvm/llvm15-thread.patch
@@ -0,0 +1,23 @@
+diff --git a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake b/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake
+index 1f2a50667c4f..d3ff232f6bd3 100644
+--- a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake
++++ b/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake
+@@ -280,4 +280,5 @@ if (NOT LIBOMPTARGET_CUDA_TOOLKIT_ROOT_DIR_PRESET AND
+   endif()
+ endif()
+ 
+-set(OPENMP_PTHREAD_LIB ${LLVM_PTHREAD_LIB})
++find_package(Threads REQUIRED)
++set(OPENMP_PTHREAD_LIB Threads::Threads)
+diff --git a/openmp/libomptarget/src/CMakeLists.txt b/openmp/libomptarget/src/CMakeLists.txt
+index 071ec61889a2..b782c3b07e6f 100644
+--- a/openmp/libomptarget/src/CMakeLists.txt
++++ b/openmp/libomptarget/src/CMakeLists.txt
+@@ -33,6 +33,7 @@ add_llvm_library(omptarget
+   LINK_LIBS 
+   PRIVATE
+   ${CMAKE_DL_LIBS}
++  ${OPENMP_PTHREAD_LIB}
+   "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports"
+   NO_INSTALL_RPATH
+ )
diff --git a/packages/llvm/package.py b/packages/llvm/package.py
index a12a7760..1334179f 100644
--- a/packages/llvm/package.py
+++ b/packages/llvm/package.py
@@ -11,59 +11,73 @@ import llnl.util.tty as tty
 
 import spack.build_environment
 import spack.util.executable
+from spack.package import *
 
 
 class Llvm(CMakePackage, CudaPackage):
     """The LLVM Project is a collection of modular and reusable compiler and
-       toolchain technologies. Despite its name, LLVM has little to do
-       with traditional virtual machines, though it does provide helpful
-       libraries that can be used to build them. The name "LLVM" itself
-       is not an acronym; it is the full name of the project.
+    toolchain technologies. Despite its name, LLVM has little to do
+    with traditional virtual machines, though it does provide helpful
+    libraries that can be used to build them. The name "LLVM" itself
+    is not an acronym; it is the full name of the project.
     """
 
     homepage = "https://llvm.org/"
     url = "https://github.com/llvm/llvm-project/archive/llvmorg-7.1.0.tar.gz"
     list_url = "https://releases.llvm.org/download.html"
     git = "https://github.com/llvm/llvm-project"
-    maintainers = ['trws', 'haampie']
+    maintainers = ["trws", "haampie"]
 
-    tags = ['e4s']
+    tags = ["e4s"]
 
-    generator = 'Ninja'
+    generator = "Ninja"
 
     family = "compiler"  # Used by lmod
 
     # fmt: off
-    version('main', branch='main')
-    version('13.0.0', sha256='a1131358f1f9f819df73fa6bff505f2c49d176e9eef0a3aedd1fdbce3b4630e8')
-    version('12.0.1', sha256='66b64aa301244975a4aea489f402f205cde2f53dd722dad9e7b77a0459b4c8df')
-    version('12.0.0', sha256='8e6c99e482bb16a450165176c2d881804976a2d770e0445af4375e78a1fbf19c')
-    version('11.1.0', sha256='53a0719f3f4b0388013cfffd7b10c7d5682eece1929a9553c722348d1f866e79')
-    version('11.0.1', sha256='9c7ad8e8ec77c5bde8eb4afa105a318fd1ded7dff3747d14f012758719d7171b')
-    version('11.0.0', sha256='8ad4ddbafac4f2c8f2ea523c2c4196f940e8e16f9e635210537582a48622a5d5')
-    version('10.0.1', sha256='c7ccb735c37b4ec470f66a6c35fbae4f029c0f88038f6977180b1a8ddc255637')
-    version('10.0.0', sha256='b81c96d2f8f40dc61b14a167513d87c0d813aae0251e06e11ae8a4384ca15451')
-    version('9.0.1', sha256='be7b034641a5fda51ffca7f5d840b1a768737779f75f7c4fd18fe2d37820289a')
-    version('9.0.0', sha256='7807fac25330e24e9955ca46cd855dd34bbc9cc4fdba8322366206654d1036f2')
-    version('8.0.1', sha256='5b18f6111c7aee7c0933c355877d4abcfe6cb40c1a64178f28821849c725c841')
-    version('8.0.0', sha256='d81238b4a69e93e29f74ce56f8107cbfcf0c7d7b40510b7879e98cc031e25167')
-    version('7.1.0', sha256='71c93979f20e01f1a1cc839a247945f556fa5e63abf2084e8468b238080fd839')
-    version('7.0.1', sha256='f17a6cd401e8fd8f811fbfbb36dcb4f455f898c9d03af4044807ad005df9f3c0')
-    version('6.0.1', sha256='aefadceb231f4c195fe6d6cd3b1a010b269c8a22410f339b5a089c2e902aa177')
-    version('6.0.0', sha256='1946ec629c88d30122afa072d3c6a89cc5d5e4e2bb28dc63b2f9ebcc7917ee64')
-    version('5.0.2', sha256='fe87aa11558c08856739bfd9bd971263a28657663cb0c3a0af01b94f03b0b795')
-    version('5.0.1', sha256='84ca454abf262579814a2a2b846569f6e0cb3e16dc33ca3642b4f1dff6fbafd3')
-    version('5.0.0', sha256='1f1843315657a4371d8ca37f01265fa9aae17dbcf46d2d0a95c1fdb3c6a4bab6')
-    version('4.0.1', sha256='cd664fb3eec3208c08fb61189c00c9118c290b3be5adb3215a97b24255618be5')
-    version('4.0.0', sha256='28ca4b2fc434cb1f558e8865386c233c2a6134437249b8b3765ae745ffa56a34')
-    version('3.9.1', sha256='f5b6922a5c65f9232f83d89831191f2c3ccf4f41fdd8c63e6645bbf578c4ab92')
-    version('3.9.0', sha256='9c6563a72c8b5b79941c773937d997dd2b1b5b3f640136d02719ec19f35e0333')
-    version('3.8.1', sha256='69360f0648fde0dc3d3c4b339624613f3bc2a89c4858933bc3871a250ad02826')
-    version('3.8.0', sha256='b5cc5974cc2fd4e9e49e1bbd0700f872501a8678bd9694fa2b36c65c026df1d1')
-    version('3.7.1', sha256='d2cb0eb9b8eb21e07605bfe5e7a5c6c5f5f8c2efdac01ec1da6ffacaabe4195a')
-    version('3.7.0', sha256='dc00bc230be2006fb87b84f6fe4800ca28bc98e6692811a98195da53c9cb28c6')
-    version('3.6.2', sha256='f75d703a388ba01d607f9cf96180863a5e4a106827ade17b221d43e6db20778a')
-    version('3.5.1', sha256='5d739684170d5b2b304e4fb521532d5c8281492f71e1a8568187bfa38eb5909d')
+    version("main", branch="main")
+    version("15.0.4", sha256="e24b4d3bf7821dcb1c901d1e09096c1f88fb00095c5a6ef893baab4836975e52")
+    version("15.0.3", sha256="8ac8e4c0982bf236526d737d385db5e1e66543ab217a9355d54159659eae3774")
+    version("15.0.2", sha256="dc11d35e60ab61792baa607dff080c993b39de23fb93b3d3369ba15b0601c307")
+    version("15.0.1", sha256="20bccb964e39f604fdc16d1258f94d2053fbdcdab2b2f6d5e20e6095ec403c00")
+    version("15.0.0", sha256="36d83cd84e1caf2bcfda1669c029e2b949adb9860cff01e7d3246ac2348b11ae")
+    version("14.0.6", sha256="98f15f842700bdb7220a166c8d2739a03a72e775b67031205078f39dd756a055")
+    version("14.0.5", sha256="a4a57f029cb81f04618e05853f05fc2d21b64353c760977d8e7799bf7218a23a")
+    version("14.0.4", sha256="1333236f9bee38658762076be4236cb5ebf15ae9b7f2bfce6946b96ae962dc73")
+    version("14.0.3", sha256="0e1d049b050127ecf6286107e9a4400b0550f841d5d2288b9d31fd32ed0683d5")
+    version("14.0.2", sha256="ca52232b3451c8e017f00eb882277707c13e30fac1271ec97015f6d0eeb383d1")
+    version("14.0.1", sha256="c8be00406e872c8a24f8571cf6f5517b73ae707104724b1fd1db2f0af9544019")
+    version("14.0.0", sha256="87b1a068b370df5b79a892fdb2935922a8efb1fddec4cc506e30fe57b6a1d9c4")
+    version("13.0.1", sha256="09c50d558bd975c41157364421820228df66632802a4a6a7c9c17f86a7340802")
+    version("13.0.0", sha256="a1131358f1f9f819df73fa6bff505f2c49d176e9eef0a3aedd1fdbce3b4630e8")
+    version("12.0.1", sha256="66b64aa301244975a4aea489f402f205cde2f53dd722dad9e7b77a0459b4c8df")
+    version("12.0.0", sha256="8e6c99e482bb16a450165176c2d881804976a2d770e0445af4375e78a1fbf19c")
+    version("11.1.0", sha256="53a0719f3f4b0388013cfffd7b10c7d5682eece1929a9553c722348d1f866e79")
+    version("11.0.1", sha256="9c7ad8e8ec77c5bde8eb4afa105a318fd1ded7dff3747d14f012758719d7171b")
+    version("11.0.0", sha256="8ad4ddbafac4f2c8f2ea523c2c4196f940e8e16f9e635210537582a48622a5d5")
+    version("10.0.1", sha256="c7ccb735c37b4ec470f66a6c35fbae4f029c0f88038f6977180b1a8ddc255637")
+    version("10.0.0", sha256="b81c96d2f8f40dc61b14a167513d87c0d813aae0251e06e11ae8a4384ca15451")
+    version("9.0.1", sha256="be7b034641a5fda51ffca7f5d840b1a768737779f75f7c4fd18fe2d37820289a")
+    version("9.0.0", sha256="7807fac25330e24e9955ca46cd855dd34bbc9cc4fdba8322366206654d1036f2")
+    version("8.0.1", sha256="5b18f6111c7aee7c0933c355877d4abcfe6cb40c1a64178f28821849c725c841")
+    version("8.0.0", sha256="d81238b4a69e93e29f74ce56f8107cbfcf0c7d7b40510b7879e98cc031e25167")
+    version("7.1.0", sha256="71c93979f20e01f1a1cc839a247945f556fa5e63abf2084e8468b238080fd839")
+    version("7.0.1", sha256="f17a6cd401e8fd8f811fbfbb36dcb4f455f898c9d03af4044807ad005df9f3c0")
+    version("6.0.1", sha256="aefadceb231f4c195fe6d6cd3b1a010b269c8a22410f339b5a089c2e902aa177")
+    version("6.0.0", sha256="1946ec629c88d30122afa072d3c6a89cc5d5e4e2bb28dc63b2f9ebcc7917ee64")
+    version("5.0.2", sha256="fe87aa11558c08856739bfd9bd971263a28657663cb0c3a0af01b94f03b0b795")
+    version("5.0.1", sha256="84ca454abf262579814a2a2b846569f6e0cb3e16dc33ca3642b4f1dff6fbafd3")
+    version("5.0.0", sha256="1f1843315657a4371d8ca37f01265fa9aae17dbcf46d2d0a95c1fdb3c6a4bab6")
+    version("4.0.1", sha256="cd664fb3eec3208c08fb61189c00c9118c290b3be5adb3215a97b24255618be5")
+    version("4.0.0", sha256="28ca4b2fc434cb1f558e8865386c233c2a6134437249b8b3765ae745ffa56a34")
+    version("3.9.1", sha256="f5b6922a5c65f9232f83d89831191f2c3ccf4f41fdd8c63e6645bbf578c4ab92")
+    version("3.9.0", sha256="9c6563a72c8b5b79941c773937d997dd2b1b5b3f640136d02719ec19f35e0333")
+    version("3.8.1", sha256="69360f0648fde0dc3d3c4b339624613f3bc2a89c4858933bc3871a250ad02826")
+    version("3.8.0", sha256="b5cc5974cc2fd4e9e49e1bbd0700f872501a8678bd9694fa2b36c65c026df1d1")
+    version("3.7.1", sha256="d2cb0eb9b8eb21e07605bfe5e7a5c6c5f5f8c2efdac01ec1da6ffacaabe4195a")
+    version("3.7.0", sha256="dc00bc230be2006fb87b84f6fe4800ca28bc98e6692811a98195da53c9cb28c6")
+    version("3.6.2", sha256="f75d703a388ba01d607f9cf96180863a5e4a106827ade17b221d43e6db20778a")
+    version("3.5.1", sha256="5d739684170d5b2b304e4fb521532d5c8281492f71e1a8568187bfa38eb5909d")
     # fmt: on
 
     # NOTE: The debug version of LLVM is an order of magnitude larger than
@@ -78,6 +92,7 @@ class Llvm(CMakePackage, CudaPackage):
     variant(
         "flang",
         default=False,
+        when="@11: +clang",
         description="Build the LLVM Fortran compiler frontend "
         "(experimental - parser only, needs GCC)",
     )
@@ -86,27 +101,29 @@ class Llvm(CMakePackage, CudaPackage):
         default=False,
         description="Include debugging code in OpenMP runtime libraries",
     )
-    variant("lldb", default=True, description="Build the LLVM debugger")
+    variant("lldb", default=True, when="+clang", description="Build the LLVM debugger")
     variant("lld", default=True, description="Build the LLVM linker")
-    variant("mlir", default=False, description="Build with MLIR support")
+    variant("mlir", default=False, when="@10:", description="Build with MLIR support")
     variant(
         "internal_unwind",
         default=True,
+        when="+clang",
         description="Build the libcxxabi libunwind",
     )
     variant(
         "polly",
         default=True,
-        description="Build the LLVM polyhedral optimization plugin, "
-        "only builds for 3.7.0+",
+        description="Build the LLVM polyhedral optimization plugin, " "only builds for 3.7.0+",
     )
     variant(
         "libcxx",
         default=True,
+        when="+clang",
         description="Build the LLVM C++ standard library",
     )
     variant(
         "compiler-rt",
+        when="+clang",
         default=True,
         description="Build LLVM compiler runtime, including sanitizers",
     )
@@ -120,32 +137,47 @@ class Llvm(CMakePackage, CudaPackage):
         default=False,
         description="Build with split dwarf information",
     )
-    variant(
-        "shared_libs",
-        default=False,
-        description="Build all components as shared libraries, faster, "
-        "less memory to build, less stable",
-    )
     variant(
         "llvm_dylib",
-        default=False,
-        description="Build LLVM shared library, containing all "
-        "components in a single shared library",
+        default=True,
+        description="Build a combined LLVM shared library with all components",
     )
     variant(
         "link_llvm_dylib",
         default=False,
+        when="+llvm_dylib",
         description="Link LLVM tools against the LLVM shared library",
     )
     variant(
         "targets",
         default="none",
-        description=("What targets to build. Spack's target family is always added "
-                     "(e.g. X86 is automatically enabled when targeting znver2)."),
-        values=("all", "none", "aarch64", "amdgpu", "arm", "avr", "bpf", "cppbackend",
-                "hexagon", "lanai", "mips", "msp430", "nvptx", "powerpc", "riscv",
-                "sparc", "systemz", "webassembly", "x86", "xcore"),
-        multi=True
+        description=(
+            "What targets to build. Spack's target family is always added "
+            "(e.g. X86 is automatically enabled when targeting znver2)."
+        ),
+        values=(
+            "all",
+            "none",
+            "aarch64",
+            "amdgpu",
+            "arm",
+            "avr",
+            "bpf",
+            "cppbackend",
+            "hexagon",
+            "lanai",
+            "mips",
+            "msp430",
+            "nvptx",
+            "powerpc",
+            "riscv",
+            "sparc",
+            "systemz",
+            "webassembly",
+            "x86",
+            "xcore",
+        ),
+        multi=True,
     )
     variant(
         "build_type",
@@ -156,31 +188,45 @@ class Llvm(CMakePackage, CudaPackage):
     variant(
         "omp_tsan",
         default=False,
+        when="@6:",
         description="Build with OpenMP capable thread sanitizer",
     )
     variant(
         "omp_as_runtime",
         default=True,
+        when="+clang @12:",
         description="Build OpenMP runtime via ENABLE_RUNTIME by just-built Clang",
     )
-    variant('code_signing', default=False,
-            description="Enable code-signing on macOS")
+    variant(
+        "code_signing",
+        default=False,
+        when="+lldb platform=darwin",
+        description="Enable code-signing on macOS",
+    )
     variant("python", default=False, description="Install python bindings")
+    variant("version_suffix", default="none", description="Add a symbol suffix")
+    variant(
+        "shlib_symbol_version",
+        default="none",
+        description="Add shared library symbol version",
+        when="@13:",
+    )
+    variant(
+        "z3", default=False, when="+clang @8:", description="Use Z3 for the clang static analyzer"
+    )
 
-    variant('version_suffix', default='none', description="Add a symbol suffix")
-    variant('z3', default=False, description='Use Z3 for the clang static analyzer')
-
-    provides('libllvm@13', when='@13.0.0:13')
-    provides('libllvm@12', when='@12.0.0:12')
-    provides('libllvm@11', when='@11.0.0:11')
-    provides('libllvm@10', when='@10.0.0:10')
-    provides('libllvm@9', when='@9.0.0:9')
-    provides('libllvm@8', when='@8.0.0:8')
-    provides('libllvm@7', when='@7.0.0:7')
-    provides('libllvm@6', when='@6.0.0:6')
-    provides('libllvm@5', when='@5.0.0:5')
-    provides('libllvm@4', when='@4.0.0:4')
-    provides('libllvm@3', when='@3.0.0:3')
+    provides("libllvm@14", when="@14.0.0:14")
+    provides("libllvm@13", when="@13.0.0:13")
+    provides("libllvm@12", when="@12.0.0:12")
+    provides("libllvm@11", when="@11.0.0:11")
+    provides("libllvm@10", when="@10.0.0:10")
+    provides("libllvm@9", when="@9.0.0:9")
+    provides("libllvm@8", when="@8.0.0:8")
+    provides("libllvm@7", when="@7.0.0:7")
+    provides("libllvm@6", when="@6.0.0:6")
+    provides("libllvm@5", when="@5.0.0:5")
+    provides("libllvm@4", when="@4.0.0:4")
+    provides("libllvm@3", when="@3.0.0:3")
 
     extends("python", when="+python")
 
@@ -230,7 +276,7 @@ class Llvm(CMakePackage, CudaPackage):
 
     # Build dependency
     depends_on("cmake@3.4.3:", type="build")
-    depends_on('cmake@3.13.4:', type='build', when='@12:')
+    depends_on("cmake@3.13.4:", type="build", when="@12:")
     depends_on("ninja", type="build")
     depends_on("python@2.7:2.8", when="@:4 ~python", type="build")
     depends_on("python", when="@5: ~python", type="build")
@@ -239,7 +285,9 @@ class Llvm(CMakePackage, CudaPackage):
     # Universal dependency
     depends_on("python@2.7:2.8", when="@:4+python")
     depends_on("python", when="@5:+python")
-    depends_on('z3', when='@8:+clang+z3')
+
+    # clang and clang-tools dependencies
+    depends_on("z3@4.7.1:", when="+z3")
 
     # openmp dependencies
     depends_on("perl-data-dumper", type=("build"))
@@ -247,12 +295,16 @@ class Llvm(CMakePackage, CudaPackage):
     depends_on("libelf", when="+cuda")  # libomptarget
     depends_on("libffi", when="+cuda")  # libomptarget
 
-    # ncurses dependency
-    depends_on("ncurses+termlib")
+    # llvm-config --system-libs libraries.
+    depends_on("zlib")
 
     # lldb dependencies
-    depends_on("swig", when="+lldb")
+    with when("+lldb +python"):
+        depends_on("swig")
+        depends_on("swig@2:", when="@10:")
+        depends_on("swig@3:", when="@12:")
     depends_on("libedit", when="+lldb")
+    depends_on("ncurses", when="+lldb")
     depends_on("py-six", when="@5.0.0: +lldb +python")
 
     # gold support, required for some features
@@ -262,23 +314,13 @@ class Llvm(CMakePackage, CudaPackage):
     depends_on("gmp", when="@:3.6 +polly")
     depends_on("isl", when="@:3.6 +polly")
 
-    conflicts("+llvm_dylib", when="+shared_libs")
-    conflicts("+link_llvm_dylib", when="~llvm_dylib")
-    conflicts("+lldb", when="~clang")
-    conflicts("+libcxx", when="~clang")
-    conflicts("+internal_unwind", when="~clang")
-    conflicts("+compiler-rt", when="~clang")
-    conflicts("+flang", when="~clang")
-    # Introduced in version 11 as a part of LLVM and not a separate package.
-    conflicts("+flang", when="@:10")
-
-    conflicts('~mlir', when='+flang', msg='Flang requires MLIR')
-
     # Older LLVM do not build with newer compilers, and vice versa
     conflicts("%gcc@8:", when="@:5")
     conflicts("%gcc@:5.0", when="@8:")
     # clang/lib: a lambda parameter cannot shadow an explicitly captured entity
     conflicts("%clang@8:", when="@:4")
+    # Internal compiler error on gcc 8.4 on aarch64 https://bugzilla.redhat.com/show_bug.cgi?id=1958295
+    conflicts("%gcc@8.4:8.4.9", when="@12: target=aarch64:")
 
     # When these versions are concretized, but not explicitly with +libcxx, these
     # conflicts will enable clingo to set ~libcxx, making the build successful:
@@ -288,116 +330,113 @@ class Llvm(CMakePackage, CudaPackage):
     # GCC    11     - latest stable release per GCC release page
     # Clang: 11, 12 - latest two stable releases per LLVM release page
     # AppleClang 12 - latest stable release per Xcode release page
-    conflicts("%gcc@:10",         when="@13:+libcxx")
-    conflicts("%clang@:10",       when="@13:+libcxx")
+    conflicts("%gcc@:10", when="@13:+libcxx")
+    conflicts("%clang@:10", when="@13:+libcxx")
     conflicts("%apple-clang@:11", when="@13:+libcxx")
 
     # libcxx-4 and compiler-rt-4 fail to build with "newer" clang and gcc versions:
-    conflicts('%gcc@7:',         when='@:4+libcxx')
-    conflicts('%clang@6:',       when='@:4+libcxx')
-    conflicts('%apple-clang@6:', when='@:4+libcxx')
-    conflicts('%gcc@7:',         when='@:4+compiler-rt')
-    conflicts('%clang@6:',       when='@:4+compiler-rt')
-    conflicts('%apple-clang@6:', when='@:4+compiler-rt')
-
-    # OMP TSAN exists in > 5.x
-    conflicts("+omp_tsan", when="@:5")
-
-
-    # OpenMP via ENABLE_RUNTIME restrictions
-    conflicts("+omp_as_runtime", when="~clang", msg="omp_as_runtime requires clang being built.")
-    conflicts("+omp_as_runtime", when="@:11.1", msg="omp_as_runtime works since LLVM 12.")
+    conflicts("%gcc@7:", when="@:4+libcxx")
+    conflicts("%clang@6:", when="@:4+libcxx")
+    conflicts("%apple-clang@6:", when="@:4+libcxx")
+    conflicts("%gcc@7:", when="@:4+compiler-rt")
+    conflicts("%clang@6:", when="@:4+compiler-rt")
+    conflicts("%apple-clang@6:", when="@:4+compiler-rt")
 
     # cuda_arch value must be specified
     conflicts("cuda_arch=none", when="+cuda", msg="A value for cuda_arch must be specified.")
 
-    # MLIR exists in > 10.x
-    conflicts("+mlir", when="@:9")
-
-    # code signing is only necessary on macOS",
-    conflicts('+code_signing', when='platform=linux')
-    conflicts('+code_signing', when='platform=cray')
-
-    conflicts(
-        '+code_signing',
-        when='~lldb platform=darwin',
-        msg="code signing is only necessary for building the "
-            "in-tree debug server on macOS. Turning this variant "
-            "off enables a build of llvm with lldb that uses the "
-            "system debug server",
-    )
-
     # LLVM bug https://bugs.llvm.org/show_bug.cgi?id=48234
     # CMake bug: https://gitlab.kitware.com/cmake/cmake/-/issues/21469
     # Fixed in upstream versions of both
-    conflicts('^cmake@3.19.0', when='@6.0.0:11.0.0')
-
-    # Starting in 3.9.0 CppBackend is no longer a target (see
-    # LLVM_ALL_TARGETS in llvm's top-level CMakeLists.txt for
-    # the complete list of targets)
-    conflicts("targets=cppbackend", when='@3.9.0:')
+    conflicts("^cmake@3.19.0", when="@6:11.0.0")
 
     # Github issue #4986
     patch("llvm_gcc7.patch", when="@4.0.0:4.0.1+lldb %gcc@7.0:")
 
     # sys/ustat.h has been removed in favour of statfs from glibc-2.28. Use fixed sizes:
-    patch('llvm5-sanitizer-ustat.patch', when="@4:6+compiler-rt")
+    patch("llvm5-sanitizer-ustat.patch", when="@4:6.0.0+compiler-rt")
 
     # Fix lld templates: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=230463
-    patch('llvm4-lld-ELF-Symbols.patch', when="@4+lld%clang@6:")
-    patch('llvm5-lld-ELF-Symbols.patch', when="@5+lld%clang@7:")
+    patch("llvm4-lld-ELF-Symbols.patch", when="@4+lld%clang@6:")
+    patch("llvm5-lld-ELF-Symbols.patch", when="@5+lld%clang@7:")
 
     # Fix missing std:size_t in 'llvm@4:5' when built with '%clang@7:'
-    patch('xray_buffer_queue-cstddef.patch', when="@4:5+compiler-rt%clang@7:")
+    patch("xray_buffer_queue-cstddef.patch", when="@4:5+compiler-rt%clang@7:")
 
     # https://github.com/llvm/llvm-project/commit/947f9692440836dcb8d88b74b69dd379d85974ce
-    patch('sanitizer-ipc_perm_mode.patch', when="@5:7+compiler-rt%clang@11:")
-    patch('sanitizer-ipc_perm_mode.patch', when="@5:9+compiler-rt%gcc@9:")
+    patch("sanitizer-ipc_perm_mode.patch", when="@5:7+compiler-rt%clang@11:")
+    patch("sanitizer-ipc_perm_mode.patch", when="@5:9+compiler-rt%gcc@9:")
 
     # github.com/spack/spack/issues/24270: MicrosoftDemangle for %gcc@10: and %clang@13:
-    patch('missing-includes.patch', when='@8')
-
-    # Backport from llvm master + additional fix
-    # see  https://bugs.llvm.org/show_bug.cgi?id=39696
-    # for a bug report about this problem in llvm master.
+    patch("missing-includes.patch", when="@8")
+
+    # Backport from llvm upstream gcc ppc const expr long double issue
+    # see https://bugs.llvm.org/show_bug.cgi?id=39696
+    # This fix was initially commited (3bf63cf3b366) for the 9.0 release
+    # but was then broken (0583d9ea8d5e) prior to the 9.0 release and
+    # eventually unbroken (d9a42ec98adc) for the 11.0 release.  The first
+    # patch backports the original correct fix to previous releases.  The
+    # second patch backports the un-breaking of the original fix.
     patch("constexpr_longdouble.patch", when="@6:8+libcxx")
-    patch("constexpr_longdouble_9.0.patch", when="@9:10.0.0+libcxx")
+    patch("constexpr_longdouble_9.0.patch", when="@9:10+libcxx")
 
     # Backport from llvm master; see
     # https://bugs.llvm.org/show_bug.cgi?id=38233
     # for a bug report about this problem in llvm master.
     patch("llvm_py37.patch", when="@4:6 ^python@3.7:")
 
-    # https://bugs.llvm.org/show_bug.cgi?id=39696
-    patch("thread-p9.patch", when="@develop+libcxx")
-
     # https://github.com/spack/spack/issues/19625,
     # merged in llvm-11.0.0_rc2, but not found in 11.0.1
     patch("lldb_external_ncurses-10.patch", when="@10.0.0:11.0.1+lldb")
 
     # https://github.com/spack/spack/issues/19908
     # merged in llvm main prior to 12.0.0
-    patch("llvm_python_path.patch", when="@11.0.0")
+    patch("llvm_python_path.patch", when="@:11")
 
     # Workaround for issue https://github.com/spack/spack/issues/18197
-    patch('llvm7_intel.patch', when='@7 %intel@18.0.2,19.0.4')
+    patch("llvm7_intel.patch", when="@7 %intel@18.0.2,19.0.0:19.1.99")
 
     # Remove cyclades support to build against newer kernel headers
     # https://reviews.llvm.org/D102059
-    patch('no_cyclades.patch', when='@10:12.0.0')
-    patch('no_cyclades9.patch', when='@6:9')
+    patch("no_cyclades.patch", when="@10:12.0.0")
+    patch("no_cyclades9.patch", when="@6:9")
+
+    patch("llvm-gcc11.patch", when="@9:11%gcc@11:")
+
+    # add -lpthread to build OpenMP libraries with Fujitsu compiler
+    patch("llvm12-thread.patch", when="@12 %fj")
+
+    # add -lpthread to build OpenMP libraries
+    patch("llvm13-14-thread.patch", when="@13:14")
+    patch("llvm15-thread.patch", when="@15")
 
-    patch('llvm-gcc11.patch', when='@9:11%gcc@11:')
+    # avoid build failed with Fujitsu compiler
+    patch("llvm13-fujitsu.patch", when="@13 %fj")
 
-    # Add LLVM_VERSION_SUFFIX
-    # https://reviews.llvm.org/D115818
-    patch('llvm-version-suffix-macro.patch', when='@:13.0.0')
+    # patch for missing hwloc.h include for libompd
+    patch("llvm14-hwloc-ompd.patch", when="@14")
+
+    # make libflags a list in openmp subproject when ~omp_as_runtime
+    patch("libomp-libflags-as-list.patch", when="@3.7:14")
+
+    # Add missing include leading to build fail with clang
+    patch(
+        "https://github.com/llvm/llvm-project/commit/b498303066a63a203d24f739b2d2e0e56dca70d1.patch?full_index=1",
+        sha256="514926d661635de47972c7d403c9c4669235aa51e22e56d44676d2a2709179b6",
+        when="@8:11",
+    )
+
+    # fix detection of LLDB_PYTHON_EXE_RELATIVE_PATH
+    # see https://reviews.llvm.org/D133513
+    # TODO: adjust version constraint and switch to fetching from the upstream GitHub repo
+    #  when/if the bugfix is merged
+    patch("D133513.diff", level=0, when="@14:15+lldb+python")
 
     # The functions and attributes below implement external package
     # detection for LLVM. See:
     #
     # https://spack.readthedocs.io/en/latest/packaging_guide.html#making-a-package-discoverable-with-spack-external-find
-    executables = ['clang', 'flang', 'ld.lld', 'lldb']
+    executables = ["clang", "flang", "ld.lld", "lldb"]
 
     @classmethod
     def filter_detected_exes(cls, prefix, exes_in_prefix):
@@ -407,7 +446,7 @@ class Llvm(CMakePackage, CudaPackage):
             # on some port and would hang Spack during detection.
             # clang-cl and clang-cpp are dev tools that we don't
             # need to test
-            if any(x in exe for x in ('vscode', 'cpp', '-cl', '-gpu')):
+            if any(x in exe for x in ("vscode", "cpp", "-cl", "-gpu")):
                 continue
             result.append(exe)
         return result
@@ -416,20 +455,20 @@ class Llvm(CMakePackage, CudaPackage):
     def determine_version(cls, exe):
         version_regex = re.compile(
             # Normal clang compiler versions are left as-is
-            r'clang version ([^ )\n]+)-svn[~.\w\d-]*|'
+            r"clang version ([^ )\n]+)-svn[~.\w\d-]*|"
             # Don't include hyphenated patch numbers in the version
             # (see https://github.com/spack/spack/pull/14365 for details)
-            r'clang version ([^ )\n]+?)-[~.\w\d-]*|'
-            r'clang version ([^ )\n]+)|'
+            r"clang version ([^ )\n]+?)-[~.\w\d-]*|"
+            r"clang version ([^ )\n]+)|"
             # LLDB
-            r'lldb version ([^ )\n]+)|'
+            r"lldb version ([^ )\n]+)|"
             # LLD
-            r'LLD ([^ )\n]+) \(compatible with GNU linkers\)'
+            r"LLD ([^ )\n]+) \(compatible with GNU linkers\)"
         )
         try:
             compiler = Executable(exe)
-            output = compiler('--version', output=str, error=str)
-            if 'Apple' in output:
+            output = compiler("--version", output=str, error=str)
+            if "Apple" in output:
                 return None
             match = version_regex.search(output)
             if match:
@@ -443,38 +482,39 @@ class Llvm(CMakePackage, CudaPackage):
 
     @classmethod
     def determine_variants(cls, exes, version_str):
-        variants, compilers = ['+clang'], {}
+        variants, compilers = ["+clang"], {}
         lld_found, lldb_found = False, False
         for exe in exes:
-            if 'clang++' in exe:
-                compilers['cxx'] = exe
-            elif 'clang' in exe:
-                compilers['c'] = exe
-            elif 'flang' in exe:
-                variants.append('+flang')
-                compilers['fc'] = exe
-                compilers['f77'] = exe
-            elif 'ld.lld' in exe:
+            if "clang++" in exe:
+                compilers["cxx"] = exe
+            elif "clang" in exe:
+                compilers["c"] = exe
+            elif "flang" in exe:
+                variants.append("+flang")
+                compilers["fc"] = exe
+                compilers["f77"] = exe
+            elif "ld.lld" in exe:
                 lld_found = True
-                compilers['ld'] = exe
-            elif 'lldb' in exe:
+                compilers["ld"] = exe
+            elif "lldb" in exe:
                 lldb_found = True
-                compilers['lldb'] = exe
+                compilers["lldb"] = exe
 
-        variants.append('+lld' if lld_found else '~lld')
-        variants.append('+lldb' if lldb_found else '~lldb')
+        variants.append("+lld" if lld_found else "~lld")
+        variants.append("+lldb" if lldb_found else "~lldb")
 
-        return ''.join(variants), {'compilers': compilers}
+        return "".join(variants), {"compilers": compilers}
 
     @classmethod
     def validate_detected_spec(cls, spec, extra_attributes):
         # For LLVM 'compilers' is a mandatory attribute
-        msg = ('the extra attribute "compilers" must be set for '
-               'the detected spec "{0}"'.format(spec))
-        assert 'compilers' in extra_attributes, msg
-        compilers = extra_attributes['compilers']
-        for key in ('c', 'cxx'):
-            msg = '{0} compiler not found for {1}'
+        msg = 'the extra attribute "compilers" must be set for ' 'the detected spec "{0}"'.format(
+            spec
+        )
+        assert "compilers" in extra_attributes, msg
+        compilers = extra_attributes["compilers"]
+        for key in ("c", "cxx"):
+            msg = "{0} compiler not found for {1}"
             assert key in compilers, msg.format(key, spec)
 
     @property
@@ -482,10 +522,10 @@ class Llvm(CMakePackage, CudaPackage):
         msg = "cannot retrieve C compiler [spec is not concrete]"
         assert self.spec.concrete, msg
         if self.spec.external:
-            return self.spec.extra_attributes['compilers'].get('c', None)
+            return self.spec.extra_attributes["compilers"].get("c", None)
         result = None
-        if '+clang' in self.spec:
-            result = os.path.join(self.spec.prefix.bin, 'clang')
+        if "+clang" in self.spec:
+            result = os.path.join(self.spec.prefix.bin, "clang")
         return result
 
     @property
@@ -493,10 +533,10 @@ class Llvm(CMakePackage, CudaPackage):
         msg = "cannot retrieve C++ compiler [spec is not concrete]"
         assert self.spec.concrete, msg
         if self.spec.external:
-            return self.spec.extra_attributes['compilers'].get('cxx', None)
+            return self.spec.extra_attributes["compilers"].get("cxx", None)
         result = None
-        if '+clang' in self.spec:
-            result = os.path.join(self.spec.prefix.bin, 'clang++')
+        if "+clang" in self.spec:
+            result = os.path.join(self.spec.prefix.bin, "clang++")
         return result
 
     @property
@@ -504,10 +544,10 @@ class Llvm(CMakePackage, CudaPackage):
         msg = "cannot retrieve Fortran compiler [spec is not concrete]"
         assert self.spec.concrete, msg
         if self.spec.external:
-            return self.spec.extra_attributes['compilers'].get('fc', None)
+            return self.spec.extra_attributes["compilers"].get("fc", None)
         result = None
-        if '+flang' in self.spec:
-            result = os.path.join(self.spec.prefix.bin, 'flang')
+        if "+flang" in self.spec:
+            result = os.path.join(self.spec.prefix.bin, "flang")
         return result
 
     @property
@@ -515,22 +555,25 @@ class Llvm(CMakePackage, CudaPackage):
         msg = "cannot retrieve Fortran 77 compiler [spec is not concrete]"
         assert self.spec.concrete, msg
         if self.spec.external:
-            return self.spec.extra_attributes['compilers'].get('f77', None)
+            return self.spec.extra_attributes["compilers"].get("f77", None)
         result = None
-        if '+flang' in self.spec:
-            result = os.path.join(self.spec.prefix.bin, 'flang')
+        if "+flang" in self.spec:
+            result = os.path.join(self.spec.prefix.bin, "flang")
         return result
 
-    @run_before('cmake')
+    @property
+    def libs(self):
+        return LibraryList(self.llvm_config("--libfiles", "all", result="list"))
+
+    @run_before("cmake")
     def codesign_check(self):
         if self.spec.satisfies("+code_signing"):
-            codesign = which('codesign')
-            mkdir('tmp')
-            llvm_check_file = join_path('tmp', 'llvm_check')
-            copy('/usr/bin/false', llvm_check_file)
+            codesign = which("codesign")
+            mkdir("tmp")
+            llvm_check_file = join_path("tmp", "llvm_check")
+            copy("/usr/bin/false", llvm_check_file)
             try:
-                codesign('-f', '-s', 'lldb_codesign', '--dryrun',
-                         llvm_check_file)
+                codesign("-f", "-s", "lldb_codesign", "--dryrun", llvm_check_file)
 
             except ProcessError:
                 # Newer LLVM versions have a simple script that sets up
@@ -540,32 +583,32 @@ class Llvm(CMakePackage, CudaPackage):
                     setup()
                 except Exception:
                     raise RuntimeError(
-                        'spack was unable to either find or set up'
-                        'code-signing on your system. Please refer to'
-                        'https://lldb.llvm.org/resources/build.html#'
-                        'code-signing-on-macos for details on how to'
-                        'create this identity.'
+                        "spack was unable to either find or set up"
+                        "code-signing on your system. Please refer to"
+                        "https://lldb.llvm.org/resources/build.html#"
+                        "code-signing-on-macos for details on how to"
+                        "create this identity."
                     )
 
     def flag_handler(self, name, flags):
-        if name == 'cxxflags':
+        if name == "cxxflags":
             flags.append(self.compiler.cxx11_flag)
-            return(None, flags, None)
-        elif name == 'ldflags' and self.spec.satisfies('%intel'):
-            flags.append('-shared-intel')
-            return(None, flags, None)
-        return(flags, None, None)
+            return (None, flags, None)
+        elif name == "ldflags" and self.spec.satisfies("%intel"):
+            flags.append("-shared-intel")
+            return (None, flags, None)
+        return (flags, None, None)
 
     def setup_build_environment(self, env):
         """When using %clang, add only its ld.lld-$ver and/or ld.lld to our PATH"""
-        if self.compiler.name in ['clang', 'apple-clang']:
-            for lld in 'ld.lld-{0}'.format(self.compiler.version.version[0]), 'ld.lld':
+        if self.compiler.name in ["clang", "apple-clang"]:
+            for lld in "ld.lld-{0}".format(self.compiler.version.version[0]), "ld.lld":
                 bin = os.path.join(os.path.dirname(self.compiler.cc), lld)
-                sym = os.path.join(self.stage.path, 'ld.lld')
+                sym = os.path.join(self.stage.path, "ld.lld")
                 if os.path.exists(bin) and not os.path.exists(sym):
                     mkdirp(self.stage.path)
                     os.symlink(bin, sym)
-            env.prepend_path('PATH', self.stage.path)
+            env.prepend_path("PATH", self.stage.path)
 
     def setup_run_environment(self, env):
         if "+clang" in self.spec:
@@ -579,23 +622,28 @@ class Llvm(CMakePackage, CudaPackage):
 
     def cmake_args(self):
         spec = self.spec
-        define = CMakePackage.define
+        define = self.define
         from_variant = self.define_from_variant
 
-        python = spec['python']
+        python = spec["python"]
         cmake_args = [
             define("LLVM_REQUIRES_RTTI", True),
             define("LLVM_ENABLE_RTTI", True),
             define("LLVM_ENABLE_EH", True),
+            define("LLVM_ENABLE_LIBXML2", False),
             define("CLANG_DEFAULT_OPENMP_RUNTIME", "libomp"),
             define("PYTHON_EXECUTABLE", python.command.path),
             define("LIBOMP_USE_HWLOC", True),
             define("LIBOMP_HWLOC_INSTALL_DIR", spec["hwloc"].prefix),
         ]
 
-        version_suffix = spec.variants['version_suffix'].value
-        if version_suffix != 'none':
-            cmake_args.append(define('LLVM_VERSION_SUFFIX', version_suffix))
+        version_suffix = spec.variants["version_suffix"].value
+        if version_suffix != "none":
+            cmake_args.append(define("LLVM_VERSION_SUFFIX", version_suffix))
+
+        shlib_symbol_version = spec.variants.get("shlib_symbol_version", None)
+        if shlib_symbol_version is not None and shlib_symbol_version.value != "none":
+            cmake_args.append(define("LLVM_SHLIB_SYMBOL_VERSION", shlib_symbol_version.value))
 
         if python.version >= Version("3"):
             cmake_args.append(define("Python3_EXECUTABLE", python.command.path))
@@ -606,44 +654,62 @@ class Llvm(CMakePackage, CudaPackage):
         runtimes = []
 
         if "+cuda" in spec:
-            cmake_args.extend([
-                define("CUDA_TOOLKIT_ROOT_DIR", spec["cuda"].prefix),
-                define("LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES",
-                       ",".join(spec.variants["cuda_arch"].value)),
-                define("CLANG_OPENMP_NVPTX_DEFAULT_ARCH",
-                       "sm_{0}".format(spec.variants["cuda_arch"].value[-1])),
-            ])
+            cmake_args.extend(
+                [
+                    define("CUDA_TOOLKIT_ROOT_DIR", spec["cuda"].prefix),
+                    define(
+                        "LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES",
+                        ",".join(spec.variants["cuda_arch"].value),
+                    ),
+                    define(
+                        "CLANG_OPENMP_NVPTX_DEFAULT_ARCH",
+                        "sm_{0}".format(spec.variants["cuda_arch"].value[-1]),
+                    ),
+                ]
+            )
             if "+omp_as_runtime" in spec:
-                cmake_args.extend([
-                    define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
-                    # work around bad libelf detection in libomptarget
-                    define("LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR",
-                           spec["libelf"].prefix.include),
-                ])
+                cmake_args.extend(
+                    [
+                        define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
+                        # work around bad libelf detection in libomptarget
+                        define(
+                            "LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR", spec["libelf"].prefix.include
+                        ),
+                    ]
+                )
         else:
             # still build libomptarget but disable cuda
-            cmake_args.extend([
-                define("CUDA_TOOLKIT_ROOT_DIR", "IGNORE"),
-                define("CUDA_SDK_ROOT_DIR", "IGNORE"),
-                define("CUDA_NVCC_EXECUTABLE", "IGNORE"),
-                define("LIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES", "IGNORE"),
-            ])
+            cmake_args.extend(
+                [
+                    define("CUDA_TOOLKIT_ROOT_DIR", "IGNORE"),
+                    define("CUDA_SDK_ROOT_DIR", "IGNORE"),
+                    define("CUDA_NVCC_EXECUTABLE", "IGNORE"),
+                    define("LIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES", "IGNORE"),
+                ]
+            )
 
         cmake_args.append(from_variant("LIBOMPTARGET_ENABLE_DEBUG", "omp_debug"))
 
         if "+lldb" in spec:
-            if spec.version >= Version('10'):
-                cmake_args.append(from_variant("LLDB_ENABLE_PYTHON", 'python'))
+            projects.append("lldb")
+            cmake_args.append(define("LLDB_ENABLE_LIBEDIT", True))
+            cmake_args.append(define("LLDB_ENABLE_CURSES", True))
+            if spec["ncurses"].satisfies("+termlib"):
+                cmake_args.append(define("LLVM_ENABLE_TERMINFO", True))
             else:
-                cmake_args.append(define("LLDB_DISABLE_PYTHON",
-                                         '~python' in spec))
+                cmake_args.append(define("LLVM_ENABLE_TERMINFO", False))
+            cmake_args.append(define("LLDB_ENABLE_LIBXML2", False))
+            if spec.version >= Version("10"):
+                cmake_args.append(from_variant("LLDB_ENABLE_PYTHON", "python"))
+            else:
+                cmake_args.append(define("LLDB_DISABLE_PYTHON", "~python" in spec))
             if spec.satisfies("@5.0.0: +python"):
                 cmake_args.append(define("LLDB_USE_SYSTEM_SIX", True))
+        else:
+            cmake_args.append(define("LLVM_ENABLE_TERMINFO", False))
 
         if "+gold" in spec:
-            cmake_args.append(
-                define("LLVM_BINUTILS_INCDIR", spec["binutils"].prefix.include)
-            )
+            cmake_args.append(define("LLVM_BINUTILS_INCDIR", spec["binutils"].prefix.include))
 
         if "+clang" in spec:
             projects.append("clang")
@@ -653,64 +719,63 @@ class Llvm(CMakePackage, CudaPackage):
             else:
                 projects.append("openmp")
 
-            if self.spec.satisfies("@8"):
-                cmake_args.append(define('CLANG_ANALYZER_ENABLE_Z3_SOLVER',
-                                         self.spec.satisfies('@8+z3')))
-            if self.spec.satisfies("@9:"):
-                cmake_args.append(define('LLVM_ENABLE_Z3_SOLVER',
-                                         self.spec.satisfies('@9:+z3')))
+            if "@8" in spec:
+                cmake_args.append(from_variant("CLANG_ANALYZER_ENABLE_Z3_SOLVER", "z3"))
+            elif "@9:" in spec:
+                cmake_args.append(from_variant("LLVM_ENABLE_Z3_SOLVER", "z3"))
 
         if "+flang" in spec:
             projects.append("flang")
-        if "+lldb" in spec:
-            projects.append("lldb")
         if "+lld" in spec:
             projects.append("lld")
         if "+compiler-rt" in spec:
-            projects.append("compiler-rt")
+            if self.spec.satisfies("@15.0.0:"):
+                runtimes.append("compiler-rt")
+            else:
+                projects.append("compiler-rt")
         if "+libcxx" in spec:
-            projects.append("libcxx")
-            projects.append("libcxxabi")
+            if self.spec.satisfies("@15.0.0:"):
+                runtimes.extend(["libcxx", "libcxxabi"])
+            else:
+                projects.extend(["libcxx", "libcxxabi"])
         if "+mlir" in spec:
             projects.append("mlir")
         if "+internal_unwind" in spec:
-            projects.append("libunwind")
+            if self.spec.satisfies("@15.0.0:"):
+                runtimes.append("libunwind")
+            else:
+                projects.append("libunwind")
         if "+polly" in spec:
             projects.append("polly")
             cmake_args.append(define("LINK_POLLY_INTO_TOOLS", True))
 
-        cmake_args.extend([
-            from_variant("BUILD_SHARED_LIBS", "shared_libs"),
-            from_variant("LLVM_BUILD_LLVM_DYLIB", "llvm_dylib"),
-            from_variant("LLVM_LINK_LLVM_DYLIB", "link_llvm_dylib"),
-            from_variant("LLVM_USE_SPLIT_DWARF", "split_dwarf"),
-            # By default on Linux, libc++.so is a ldscript. CMake fails to add
-            # CMAKE_INSTALL_RPATH to it, which fails. Statically link libc++abi.a
-            # into libc++.so, linking with -lc++ or -stdlib=libc++ is enough.
-            define('LIBCXX_ENABLE_STATIC_ABI_LIBRARY', True)
-        ])
-
-        cmake_args.append(define(
-            "LLVM_TARGETS_TO_BUILD",
-            get_llvm_targets_to_build(spec)))
+        cmake_args.extend(
+            [
+                define("BUILD_SHARED_LIBS", False),
+                from_variant("LLVM_BUILD_LLVM_DYLIB", "llvm_dylib"),
+                from_variant("LLVM_LINK_LLVM_DYLIB", "link_llvm_dylib"),
+                from_variant("LLVM_USE_SPLIT_DWARF", "split_dwarf"),
+                # By default on Linux, libc++.so is a ldscript. CMake fails to add
+                # CMAKE_INSTALL_RPATH to it, which fails. Statically link libc++abi.a
+                # into libc++.so, linking with -lc++ or -stdlib=libc++ is enough.
+                define("LIBCXX_ENABLE_STATIC_ABI_LIBRARY", True),
+            ]
+        )
+
+        cmake_args.append(define("LLVM_TARGETS_TO_BUILD", get_llvm_targets_to_build(spec)))
 
         cmake_args.append(from_variant("LIBOMP_TSAN_SUPPORT", "omp_tsan"))
 
         if self.compiler.name == "gcc":
-            compiler = Executable(self.compiler.cc)
-            gcc_output = compiler('-print-search-dirs', output=str, error=str)
-
-            for line in gcc_output.splitlines():
-                if line.startswith("install:"):
-                    # Get path and strip any whitespace
-                    # (causes oddity with ancestor)
-                    gcc_prefix = line.split(":")[1].strip()
-                    gcc_prefix = ancestor(gcc_prefix, 4)
-                    break
-            cmake_args.append(define("GCC_INSTALL_PREFIX", gcc_prefix))
+            cmake_args.append(define("GCC_INSTALL_PREFIX", self.compiler.prefix))
 
         if self.spec.satisfies("~code_signing platform=darwin"):
-            cmake_args.append(define('LLDB_USE_SYSTEM_DEBUGSERVER', True))
+            cmake_args.append(define("LLDB_USE_SYSTEM_DEBUGSERVER", True))
+
+        # Enable building with CLT [and not require full Xcode]
+        # https://github.com/llvm/llvm-project/issues/57037
+        if self.spec.satisfies("@15.0.0: platform=darwin"):
+            cmake_args.append(define("BUILTINS_CMAKE_ARGS", "-DCOMPILER_RT_ENABLE_IOS=OFF"))
 
         # Semicolon seperated list of projects to enable
         cmake_args.append(define("LLVM_ENABLE_PROJECTS", projects))
@@ -724,7 +789,7 @@ class Llvm(CMakePackage, CudaPackage):
     @run_after("install")
     def post_install(self):
         spec = self.spec
-        define = CMakePackage.define
+        define = self.define
 
         # unnecessary if we build openmp via LLVM_ENABLE_RUNTIMES
         if "+cuda ~omp_as_runtime" in self.spec:
@@ -734,20 +799,24 @@ class Llvm(CMakePackage, CudaPackage):
             # rebuild libomptarget to get bytecode runtime library files
             with working_dir(ompdir, create=True):
                 cmake_args = [
-                    '-G', 'Ninja',
-                    define('CMAKE_BUILD_TYPE', spec.variants['build_type'].value),
+                    "-G",
+                    "Ninja",
+                    define("CMAKE_BUILD_TYPE", spec.variants["build_type"].value),
                     define("CMAKE_C_COMPILER", spec.prefix.bin + "/clang"),
                     define("CMAKE_CXX_COMPILER", spec.prefix.bin + "/clang++"),
                     define("CMAKE_INSTALL_PREFIX", spec.prefix),
-                    define('CMAKE_PREFIX_PATH', prefix_paths)
+                    define("CMAKE_PREFIX_PATH", prefix_paths),
                 ]
                 cmake_args.extend(self.cmake_args())
-                cmake_args.extend([
-                    define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
-                    define("LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR",
-                           spec["libelf"].prefix.include),
-                    self.stage.source_path + "/openmp",
-                ])
+                cmake_args.extend(
+                    [
+                        define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
+                        define(
+                            "LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR", spec["libelf"].prefix.include
+                        ),
+                        self.stage.source_path + "/openmp",
+                    ]
+                )
 
                 cmake(*cmake_args)
                 ninja()
@@ -762,13 +831,14 @@ class Llvm(CMakePackage, CudaPackage):
             install_tree("bin", join_path(self.prefix, "libexec", "llvm"))
 
     def llvm_config(self, *args, **kwargs):
-        lc = Executable(self.prefix.bin.join('llvm-config'))
-        if not kwargs.get('output'):
-            kwargs['output'] = str
+        lc = Executable(self.prefix.bin.join("llvm-config"))
+        if not kwargs.get("output"):
+            kwargs["output"] = str
         ret = lc(*args, **kwargs)
-        if kwargs.get('output') == "list":
+        if kwargs.get("result") == "list":
             return ret.split()
-        return ret
+        else:
+            return ret
 
     # ECM: might be not needed anymore?
     def add_files_to_view(self, view, merge_map, skip_if_exists=True):
@@ -786,11 +856,11 @@ class Llvm(CMakePackage, CudaPackage):
         super(Llvm, self).add_files_to_view(view, merge_map, skip_if_exists=True)
 
 def get_llvm_targets_to_build(spec):
-    targets = spec.variants['targets'].value
+    targets = spec.variants["targets"].value
 
     # Build everything?
-    if 'all' in targets:
-        return 'all'
+    if "all" in targets:
+        return "all"
 
     # Convert targets variant values to CMake LLVM_TARGETS_TO_BUILD array.
     spack_to_cmake = {
@@ -811,10 +881,10 @@ def get_llvm_targets_to_build(spec):
         "systemz": "SystemZ",
         "webassembly": "WebAssembly",
         "x86": "X86",
-        "xcore": "XCore"
+        "xcore": "XCore",
     }
 
-    if 'none' in targets:
+    if "none" in targets:
         llvm_targets = set()
     else:
         llvm_targets = set(spack_to_cmake[target] for target in targets)
-- 
GitLab