From 913084d5f69318502760ae402b4dfc70a6c4446c Mon Sep 17 00:00:00 2001
From: David Abdurachmanov <davidlt@cern.ch>
Date: Mon, 24 Apr 2017 10:18:52 +0200
Subject: [PATCH] Add C++17 (C++1z) mode to build scripts for ROOT and LLVM

The patch adds C++17 (C++1z) mode to ROOT and LLVM. This requires
GCC 7.1.0 which supports full C++17 standard. It's to be released
soon (probably within a month). C++14 continues to be default standard
version in GCC 7.1.0.

This C++17 option is not enabled by default.

Signed-off-by: David Abdurachmanov <davidlt@cern.ch>
---
 cmake/modules/CheckCompiler.cmake               | 17 +++++++++++++++++
 cmake/modules/RootBuildOptions.cmake            |  1 +
 cmake/modules/RootConfiguration.cmake           |  8 +++++++-
 config/RConfigure.in                            |  1 +
 config/root-config.in                           | 10 +++++-----
 interpreter/CMakeLists.txt                      |  4 +++-
 interpreter/llvm/src/CMakeLists.txt             |  1 +
 .../src/cmake/modules/HandleLLVMOptions.cmake   |  3 +++
 8 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/cmake/modules/CheckCompiler.cmake b/cmake/modules/CheckCompiler.cmake
index ebe419983f3..b35758feee3 100644
--- a/cmake/modules/CheckCompiler.cmake
+++ b/cmake/modules/CheckCompiler.cmake
@@ -89,6 +89,11 @@ if(cxx11 AND cxx14)
   message(STATUS "c++11 mode requested but superseded by request for c++14 mode")
   set(cxx11 OFF CACHE BOOL "" FORCE)
 endif()
+if((cxx11 OR cxx14) AND cxx17)
+  message(STATUS "c++11 or c++14 mode requested but superseded by request for c++17 mode")
+  set(cxx11 OFF CACHE BOOL "" FORCE)
+  set(cxx14 OFF CACHE BOOL "" FORCE)
+endif()
 if(cxx11)
   CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CXX11)
   if(NOT HAS_CXX11)
@@ -104,6 +109,14 @@ if(cxx14)
   endif()
   set(root7 On)
 endif()
+if(cxx17)
+  CHECK_CXX_COMPILER_FLAG("-std=c++1z" HAS_CXX17)
+  if(NOT HAS_CXX17)
+    message(STATUS "Current compiler does not suppport -std=c++17 option. Switching OFF cxx17 option")
+    set(cxx17 OFF CACHE BOOL "" FORCE)
+  endif()
+  set(root7 On)
+endif()
 if(root7)
   if(NOT cxx14)
     message(STATUS "ROOT7 interfaces require cxx14 which is disabled. Switching OFF root7 option")
@@ -151,6 +164,10 @@ if(cxx14)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
 endif()
 
+if(cxx17)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z")
+endif()
+
 if(libcxx)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
 endif()
diff --git a/cmake/modules/RootBuildOptions.cmake b/cmake/modules/RootBuildOptions.cmake
index 2d49c5ad0d6..d218d5de4ec 100644
--- a/cmake/modules/RootBuildOptions.cmake
+++ b/cmake/modules/RootBuildOptions.cmake
@@ -98,6 +98,7 @@ ROOT_BUILD_OPTION(cocoa OFF "Use native Cocoa/Quartz graphics backend (MacOS X o
 ROOT_BUILD_OPTION(cuda OFF "Use CUDA if it is found in the system")
 ROOT_BUILD_OPTION(cxx11 ON "Build using C++11 compatible mode, requires gcc > 4.7.x or clang")
 ROOT_BUILD_OPTION(cxx14 OFF "Build using C++14 compatible mode, requires gcc > 4.9.x or clang")
+ROOT_BUILD_OPTION(cxx17 OFF "Build using C++17 compatible mode, requires gcc >= 7.1.0 or clang")
 ROOT_BUILD_OPTION(cxxmodules "Compile with C++ modules enabled." OFF)
 ROOT_BUILD_OPTION(davix ON "DavIx library for HTTP/WEBDAV access")
 ROOT_BUILD_OPTION(dcache ON "dCache support, requires libdcap from DESY")
diff --git a/cmake/modules/RootConfiguration.cmake b/cmake/modules/RootConfiguration.cmake
index 1f7843f021c..e8c22cc6cea 100644
--- a/cmake/modules/RootConfiguration.cmake
+++ b/cmake/modules/RootConfiguration.cmake
@@ -479,6 +479,12 @@ if(cxx14)
 else()
   set(usec++14 undef)
 endif()
+if(cxx17)
+  set(cxxversion cxx17)
+  set(usec++17 define)
+else()
+  set(usec++17 undef)
+endif()
 if(libcxx)
   set(uselibc++ define)
 else()
@@ -493,7 +499,7 @@ else()
 endif()
 
 CHECK_CXX_SOURCE_COMPILES("#include <string_view>
-  int main() { std::string_view().to_string(); return 0;}" found_stdstringview)
+  int main() { char arr[3] = {'B', 'a', 'r'}; std::string_view strv(arr, sizeof(arr)); return 0;}" found_stdstringview)
 if(found_stdstringview)
   set(hasstdstringview define)
 else()
diff --git a/config/RConfigure.in b/config/RConfigure.in
index c0601629cac..488f8befe0b 100644
--- a/config/RConfigure.in
+++ b/config/RConfigure.in
@@ -27,6 +27,7 @@
 #@hasvc@ R__HAS_VC    /**/
 #@usec++11@ R__USE_CXX11    /**/
 #@usec++14@ R__USE_CXX14    /**/
+#@usec++17@ R__USE_CXX17    /**/
 #@uselibc++@ R__USE_LIBCXX    /**/
 #@hasstdstringview@ R__HAS_STD_STRING_VIEW   /**/
 #@hasstdexpstringview@ R__HAS_STD_EXPERIMENTAL_STRING_VIEW   /**/
diff --git a/config/root-config.in b/config/root-config.in
index 1b4cdbafbe2..3b6e6006282 100755
--- a/config/root-config.in
+++ b/config/root-config.in
@@ -147,11 +147,11 @@ fi
 
 ### machine dependent settings ###
 
-if test "x$cxxversion" = "xcxx14" ; then
-   cxxversionflag="-std=c++1y "
-else
-   cxxversionflag="-std=c++11 "
-fi
+case "$cxxversion" in
+  cxx17) cxxversionflag="-std=c++1z " ;;
+  cxx14) cxxversionflag="-std=c++1y " ;;
+  *)     cxxversionflag="-std=c++11 " ;;
+esac
 
 case $arch in
 aix5)
diff --git a/interpreter/CMakeLists.txt b/interpreter/CMakeLists.txt
index 6a3cb5658fb..c220b7d7c86 100644
--- a/interpreter/CMakeLists.txt
+++ b/interpreter/CMakeLists.txt
@@ -9,7 +9,9 @@ set(LLVM_FORCE_USE_OLD_TOOLCHAIN ON CACHE BOOL "")
 # to serialize access to llvm.  We can later review how to make this finer grained by using llvm's own locking
 # mechanism.
 set(LLVM_ENABLE_THREADS OFF CACHE BOOL "")
-if(cxx14)
+if(cxx17)
+  set(LLVM_ENABLE_CXX1Z ON CACHE BOOL "" FORCE)
+elseif(cxx14)
   set(LLVM_ENABLE_CXX1Y ON CACHE BOOL "" FORCE)
 endif()
 
diff --git a/interpreter/llvm/src/CMakeLists.txt b/interpreter/llvm/src/CMakeLists.txt
index b9e11011ba2..ab7ff671548 100644
--- a/interpreter/llvm/src/CMakeLists.txt
+++ b/interpreter/llvm/src/CMakeLists.txt
@@ -291,6 +291,7 @@ else()
   option(LLVM_ENABLE_LOCAL_SUBMODULE_VISIBILITY "Compile with -fmodules-local-submodule-visibility." ON)
 endif()
 option(LLVM_ENABLE_CXX1Y "Compile with C++1y enabled." OFF)
+option(LLVM_ENABLE_CXX1Z "Compile with C++1z enabled." OFF)
 option(LLVM_ENABLE_LIBCXX "Use libc++ if available." OFF)
 option(LLVM_ENABLE_LIBCXXABI "Use libc++abi when using libc++." OFF)
 option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
diff --git a/interpreter/llvm/src/cmake/modules/HandleLLVMOptions.cmake b/interpreter/llvm/src/cmake/modules/HandleLLVMOptions.cmake
index fc3027e6c59..a162e3f82d4 100644
--- a/interpreter/llvm/src/cmake/modules/HandleLLVMOptions.cmake
+++ b/interpreter/llvm/src/cmake/modules/HandleLLVMOptions.cmake
@@ -451,6 +451,9 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
   if (LLVM_ENABLE_CXX1Y)
     check_cxx_compiler_flag("-std=c++1y" CXX_SUPPORTS_CXX1Y)
     append_if(CXX_SUPPORTS_CXX1Y "-std=c++1y" CMAKE_CXX_FLAGS)
+  elseif(LLVM_ENABLE_CXX1Z)
+    check_cxx_compiler_flag("-std=c++1z" CXX_SUPPORTS_CXX1Z)
+    append_if(CXX_SUPPORTS_CXX1Z "-std=c++1z" CMAKE_CXX_FLAGS)
   else()
     check_cxx_compiler_flag("-std=c++11" CXX_SUPPORTS_CXX11)
     if (CXX_SUPPORTS_CXX11)
-- 
GitLab