diff --git a/CMakeLists.txt b/CMakeLists.txt index a54379c..6ae97bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,14 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 4.0) enable_testing() project(O2CodeChecker) +# LLVM's installed HandleLLVMOptions.cmake sets no C++ standard, so without this +# we inherit whatever the compiler defaults to -- C++14 on Apple clang, which is +# not enough for the clang-tidy headers. +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + # find clang + llvm find_package(Clang REQUIRED CONFIG) diff --git a/aliceO2/AliceO2TidyModule.cpp b/aliceO2/AliceO2TidyModule.cpp index 71f5ac1..4c6f73d 100644 --- a/aliceO2/AliceO2TidyModule.cpp +++ b/aliceO2/AliceO2TidyModule.cpp @@ -9,7 +9,14 @@ #include "clang-tidy/ClangTidy.h" #include "clang-tidy/ClangTidyModule.h" +// Up to Clang 21 ClangTidyModuleRegistry was declared only in +// ClangTidyModuleRegistry.h. Clang 22 moved it into ClangTidyModule.h above and +// left the old header behind as a bare #warning, to be deleted in Clang 24 -- +// so __has_include() would keep including it, and keep warning, on 22 and 23. +#include "llvm/Config/llvm-config.h" +#if LLVM_VERSION_MAJOR < 22 #include "clang-tidy/ClangTidyModuleRegistry.h" +#endif #include "MemberNamesCheck.h" #include "NamespaceNamingCheck.h" #include "SizeofCheck.h" diff --git a/aliceO2/NamespaceNamingCheck.cpp b/aliceO2/NamespaceNamingCheck.cpp index ca9790a..000399b 100644 --- a/aliceO2/NamespaceNamingCheck.cpp +++ b/aliceO2/NamespaceNamingCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchersMacros.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "llvm/Config/llvm-config.h" // LLVM_VERSION_MAJOR #include #include #include @@ -98,7 +99,23 @@ void NamespaceNamingCheck::check(const MatchFinder::MatchResult &Result) { const auto *MatchedNamespaceLoc = Result.Nodes.getNodeAs("namespace-usage"); if( MatchedNamespaceLoc ) { - const auto *AsNamespace = MatchedNamespaceLoc->getNestedNameSpecifier()->getAsNamespace(); +#if LLVM_VERSION_MAJOR >= 22 + // Clang 22 turned NestedNameSpecifier into a value type and removed + // getAsNamespace(); the namespace is now reached through + // getAsNamespaceAndPrefix(), which is llvm_unreachable() unless the + // specifier really designates one. The matcher below only binds + // specifiesNamespace(), but check the kind rather than trust that. It also + // yields a NamespaceBaseDecl, the new common base of NamespaceDecl and + // NamespaceAliasDecl; both are NamedDecl, which is all we use below. + const NestedNameSpecifier Qualifier = MatchedNamespaceLoc->getNestedNameSpecifier(); + if( Qualifier.getKind() != NestedNameSpecifier::Kind::Namespace ) + { + return; + } + const NamespaceBaseDecl *AsNamespace = Qualifier.getAsNamespaceAndPrefix().Namespace; +#else + const NamespaceDecl *AsNamespace = MatchedNamespaceLoc->getNestedNameSpecifier()->getAsNamespace(); +#endif if( isOutsideOfTargetScope( Result.SourceManager->getFilename(AsNamespace->getLocation()).str() ) ) { return;