diff --git a/libcxx/docs/TestingLibcxx.rst b/libcxx/docs/TestingLibcxx.rst --- a/libcxx/docs/TestingLibcxx.rst +++ b/libcxx/docs/TestingLibcxx.rst @@ -112,6 +112,9 @@ These tools are: - clang-tidy (you might need additional dev packages to compile libc++-specific clang-tidy checks) +These tools are build using the system's default C++ Standard library. +Therefore this library should meet LLVM's minimum requirement of C++17 support. + Reproducing CI issues locally ----------------------------- diff --git a/libcxx/test/tools/README.md b/libcxx/test/tools/README.md new file mode 100644 --- /dev/null +++ b/libcxx/test/tools/README.md @@ -0,0 +1,5 @@ +# The libc++ tooling + +These tools are used for testing libc++. The clang-tidy plugin is build with +the system's C++ Standard library implementation. This library should match +LLVM's minimim requirement of C++17 support. diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt --- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt +++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt @@ -37,7 +37,7 @@ message(STATUS "Found system-installed LLVM ${LLVM_PACKAGE_VERSION} with headers in ${LLVM_INCLUDE_DIRS}") -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 17) # Link only against clangTidy itself, not anything that clangTidy uses; otherwise we run setup code multiple times # which results in clang-tidy crashing @@ -62,7 +62,7 @@ target_link_libraries(cxx-tidy clangTidy) set_target_properties(cxx-tidy PROPERTIES - CXX_STANDARD 20 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO) diff --git a/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp --- a/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp +++ b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp @@ -60,8 +60,7 @@ } std::optional list = Options.get("SkipDeclarations"); - // TODO(LLVM-17) Remove clang 15 work-around. -#if defined(__clang_major__) && __clang_major__ < 16 +#if __cplusplus <= 201703L if (list) { std::string_view s = *list; auto b = s.begin(); @@ -74,35 +73,34 @@ e = std::find(b, s.end(), ' '); } } -#else // defined(__clang_major__) && __clang_major__ < 16 +#else // __cplusplus <= 201703 if (list) for (auto decl : std::views::split(*list, ' ')) { std::string s; std::ranges::copy(decl, std::back_inserter(s)); // use range based constructor decls_.emplace(std::move(s)); } -#endif // defined(__clang_major__) && __clang_major__ < 16 +#endif // __cplusplus <= 201703 list = Options.get("ExtraDeclarations"); - // TODO(LLVM-17) Remove clang 15 work-around. -#if defined(__clang_major__) && __clang_major__ < 16 +#if __cplusplus <= 201703 if (list) { std::string_view s = *list; auto b = s.begin(); auto e = std::find(b, s.end(), ' '); while (b != e) { - std::cout << "using " << std::string_view{b, e} << ";\n"; + std::cout << "using " << std::string{b, e} << ";\n"; if (e == s.end()) break; b = e + 1; e = std::find(b, s.end(), ' '); } } -#else // defined(__clang_major__) && __clang_major__ < 16 +#else // __cplusplus <= 201703 if (list) for (auto decl : std::views::split(*list, ' ')) std::cout << "using " << std::string_view{decl.data(), decl.size()} << ";\n"; -#endif // defined(__clang_major__) && __clang_major__ < 16 +#endif // __cplusplus <= 201703 } void header_exportable_declarations::registerMatchers(clang::ast_matchers::MatchFinder* finder) { @@ -157,7 +155,7 @@ static std::string get_qualified_name(const clang::NamedDecl& decl) { std::string result = decl.getQualifiedNameAsString(); - if (result.starts_with("std::__1::")) + if (result.find("std::__1::") == 0) result.erase(5, 5); return result; @@ -229,7 +227,7 @@ if (clang::Module* M = decl->getOwningModule(); M && M->Kind != clang::Module::ModulePartitionInterface) return; - if (decls_.contains(name)) + if (decls_.count(name)) return; std::cout << "using " << std::string{name} << ";\n"; diff --git a/libcxx/test/tools/clang_tidy_checks/proper_version_checks.cpp b/libcxx/test/tools/clang_tidy_checks/proper_version_checks.cpp --- a/libcxx/test/tools/clang_tidy_checks/proper_version_checks.cpp +++ b/libcxx/test/tools/clang_tidy_checks/proper_version_checks.cpp @@ -39,21 +39,21 @@ if (preprocessor_.getSourceManager().isInMainFile(location)) return; - if (condition.starts_with("_LIBCPP_STD_VER") && condition.find(">") != std::string_view::npos && + if (condition.find("_LIBCPP_STD_VER") == 0 && condition.find(">") != std::string_view::npos && condition.find(">=") == std::string_view::npos) check_.diag(location, "_LIBCPP_STD_VER >= version should be used instead of _LIBCPP_STD_VER > prev_version"); - else if (condition.starts_with("__cplusplus")) + else if (condition.find("__cplusplus") == 0) check_.diag(location, "Use _LIBCPP_STD_VER instead of __cplusplus to constrain based on the C++ version"); else if (condition == "_LIBCPP_STD_VER >= 11") check_.diag(location, "_LIBCPP_STD_VER >= 11 is always true. Did you mean '#ifndef _LIBCPP_CXX03_LANG'?"); - else if (condition.starts_with("_LIBCPP_STD_VER >= ") && - std::ranges::none_of(std::array{"14", "17", "20", "23", "26"}, [&](auto val) { - return condition.find(val) != std::string_view::npos; - })) - check_.diag(location, "Not a valid value for _LIBCPP_STD_VER. Use 14, 17, 20, 23, or 26"); + else if (condition.find("_LIBCPP_STD_VER >= ") == 0) { + std::array a{"14", "17", "20", "23", "26"}; + if (std ::none_of(a.begin(), a.end(), [&](auto val) { return condition.find(val) != std::string_view::npos; })) + check_.diag(location, "Not a valid value for _LIBCPP_STD_VER. Use 14, 17, 20, 23, or 26"); + } } clang::Preprocessor& preprocessor_; diff --git a/libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp b/libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp --- a/libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp +++ b/libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp @@ -19,9 +19,8 @@ AST_MATCHER(clang::CallExpr, isOperator) { return llvm::isa(Node); } AST_MATCHER(clang::UnresolvedLookupExpr, isCustomizationPoint) { - return std::ranges::any_of( - std::array{"swap", "make_error_code", "make_error_condition", "begin", "end", "size", "rend", "rbegin"}, - [&](const char* func) { return Node.getName().getAsString() == func; }); + std::array a{"swap", "make_error_code", "make_error_condition", "begin", "end", "size", "rend", "rbegin"}; + return std::any_of(a.begin(), a.end(), [&](const char* func) { return Node.getName().getAsString() == func; }); } AST_MATCHER(clang::CXXMethodDecl, isStatic) { return Node.isStatic(); } diff --git a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp --- a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp +++ b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp @@ -25,21 +25,8 @@ return str.find("__") != std::string_view::npos; } -// Starting with Clang 17 ToT C++23 support is provided by CPlusPlus23 instead -// of C++23 support is provided by CPlusPlus2b. To allow a smooth transition for -// libc++ use "reflection" to select the proper member. Since the change -// happens in the development cycle it's not possible to use #ifdefs. template -bool CPlusPlus23(const T& lang_opts) - requires requires { T::CPlusPlus2b; } -{ - return lang_opts.CPlusPlus2b; -} - -template -bool CPlusPlus23(const T& lang_opts) - requires requires { T::CPlusPlus23; } -{ +bool CPlusPlus23(const T& lang_opts) { return lang_opts.CPlusPlus23; }