From f9d7a9121098c1948581b314bb55ed95ead7cc2f Mon Sep 17 00:00:00 2001 From: Miuna Date: Wed, 26 Jul 2023 14:25:35 -0400 Subject: [PATCH] fix: coroutines: better support for clang, remove experimental if unneeded, add missing headers --- include/dpp/coro.h | 27 ++++++++++++++++++++------ library/CMakeLists.txt | 44 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/include/dpp/coro.h b/include/dpp/coro.h index 53ea155b9f..4f912d823d 100644 --- a/include/dpp/coro.h +++ b/include/dpp/coro.h @@ -1,11 +1,21 @@ #ifdef DPP_CORO #pragma once -#if !(defined( _MSC_VER ) || defined( _CONSOLE ) || defined( __GNUC__ )) // if libc++ -# define EXPERIMENTAL_COROUTINE +#if (defined(_LIBCPP_VERSION) and !defined(__cpp_impl_coroutine)) // if libc++ experimental implementation (LLVM < 14) +# define STDCORO_EXPERIMENTAL_HEADER +# define STDCORO_EXPERIMENTAL_NAMESPACE #endif -#ifdef EXPERIMENTAL_COROUTINE +#ifdef STDCORO_GLIBCXX_COMPAT +# define __cpp_impl_coroutine 1 +namespace std { + namespace experimental { + using namespace std; + } +} +#endif + +#ifdef STDCORO_EXPERIMENTAL_HEADER # include #else # include @@ -14,6 +24,11 @@ #include #include #include +#include +#include +#include +#include +#include namespace dpp { class cluster; @@ -33,7 +48,7 @@ namespace dpp { */ namespace std_coroutine {} #else -# ifdef EXPERIMENTAL_COROUTINE +# ifdef STDCORO_EXPERIMENTAL_NAMESPACE namespace std_coroutine = std::experimental; # else namespace std_coroutine = std; @@ -282,7 +297,7 @@ namespace dpp { * * @return std::suspend_never Don't suspend, the coroutine starts immediately. */ - std::suspend_never initial_suspend() noexcept { + std_coroutine::suspend_never initial_suspend() noexcept { return {}; } @@ -454,7 +469,7 @@ namespace dpp { * * @see std::coroutine_handle */ - std::coroutine_handle<> coro_handle = nullptr; + detail::std_coroutine::coroutine_handle<> coro_handle = nullptr; }; /** diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 4bf20455bf..e74c4e33bb 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -293,17 +293,51 @@ if(HAVE_PTHREAD_SETNAME_NP) endif() if(DPP_CORO) - message("-- ${Yellow}Enabled experimental coroutine support${ColourReset}") + message("-- ${Yellow}Enabled experimental coroutine feature${ColourReset}") set(CMAKE_CXX_STANDARD 20) target_compile_features(dpp PUBLIC cxx_std_20) if(WIN32 AND NOT MINGW) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /await:strict") else() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - target_link_libraries(dpp PUBLIC "c++abi") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0.0) # clang >= 14 has native support + message("-- ${Yellow}Clang < 14 - attempting to detect if using libc++ or stdc++${ColourReset}") + check_cxx_source_compiles(" + #include + + int a = + #ifdef __GLIBCXX__ + 1; + #else + fgsfds; + #endif + + int main(int argc, char* argv[]) + { + return 0; + } + " IS_GLIBCXX) + if(IS_GLIBCXX) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0.0) + message(FATAL_ERROR "Clang with stdc++ and coroutines requires version 12.0.0 or above") + endif() + message("-- ${Yellow}Detected stdc++ - enabling mock std::experimental namespace${ColourReset}") + target_compile_definitions(dpp PUBLIC "STDCORO_GLIBCXX_COMPAT") + else() + message("-- ${Yellow}Detected libc++ - using ") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0.0) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines-ts") + endif() + endif() + message("-- ${Yellow}Note - coroutines in clang < 14 are experimental, upgrading is recommended") + endif() + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) + message(FATAL_ERROR "Coroutines with g++ require version 10 or above") + elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0) + message("-- ${Yellow}Note - coroutines in g++10 are experimental, upgrading to g++11 or above is recommended") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines") + endif() endif() endif() target_compile_definitions(dpp PUBLIC DPP_CORO)