Browse Source

Features: Enable writing of MSVC compiler feature header.

Notes:
VS2015 and above are the only MSVC versions to support cxx_final, so remove
usages from the tests, and instead only test for cxx_override.

VS2012 and above to conform to cxx_decltype_incomplete_return_types
proposal, but without support for auto return types the dcl.type.simple
example in the proposal doesn't compile.

VS2013 and above to conform to the updated cxx_contextual_conversions proposal,
but VS2010 and above pass the test.

Compilers such as MSVC have no explicit flags to enable C++11 mode,
it just is always on. So only run the link tests with compilers that require
a flag to specify the language version.
Robert Maynard 11 years ago
parent
commit
f73718c9b8

+ 3 - 2
Modules/WriteCompilerDetectionHeader.cmake

@@ -36,7 +36,7 @@
 #      PREFIX ClimbingStats
 #      OUTPUT_FILES_VAR support_files
 #      OUTPUT_DIR compilers
-#      COMPILERS GNU Clang
+#      COMPILERS GNU Clang MSVC
 #      FEATURES cxx_variadic_templates
 #    )
 #    install(FILES
@@ -100,7 +100,7 @@
 #    write_compiler_detection_header(
 #      FILE climbingstats_compiler_detection.h
 #      PREFIX ClimbingStats
-#      COMPILERS GNU Clang AppleClang
+#      COMPILERS GNU Clang AppleClang MSVC
 #      FEATURES cxx_variadic_templates
 #    )
 #
@@ -316,6 +316,7 @@ function(write_compiler_detection_header
     GNU
     Clang
     AppleClang
+    MSVC
   )
 
   set(_hex_compilers ADSP Borland Embarcadero SunPro)

+ 23 - 0
Tests/CompileFeatures/CMakeLists.txt

@@ -26,7 +26,18 @@ get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
 foreach(feature ${c_features})
   run_test(${feature} C)
 endforeach()
+
 get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+  list(REMOVE_ITEM cxx_features
+    # This test requires auto return type deduction to work properly, but
+    # that is not supported by all versions of MSVC that support decltype
+    # incomplete return types.
+    cxx_decltype_incomplete_return_types
+    )
+endif()
+
 foreach(feature ${cxx_features})
   run_test(${feature} CXX)
 endforeach()
@@ -53,6 +64,17 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
   )
 endif()
 
+set(MSVC_)
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND
+   MSVC_VERSION LESS 1800)
+  list(REMOVE_ITEM CXX_non_features
+    # Microsoft only officially supports this feature in VS2013 and above, due
+    # to new wording of the proposal. We don't test for this with MSVC because
+    # older compiler pass the test but might not actually conform
+    cxx_contextual_conversions
+    )
+endif()
+
 set(C_ext c)
 set(C_standard_flag 11)
 set(CXX_ext cpp)
@@ -126,6 +148,7 @@ if (CMAKE_CXX_COMPILE_FEATURES)
 
   add_executable(CompileFeaturesGenex genex_test.cpp)
   set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11)
+
   target_compile_definitions(CompileFeaturesGenex PRIVATE
     HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
     HAVE_NULLPTR=$<COMPILE_FEATURES:cxx_nullptr>

+ 1 - 1
Tests/CompileFeatures/genex_test.cpp

@@ -10,7 +10,7 @@ struct A
   virtual int getA() { return 7; }
 };
 
-struct B final : A
+struct B : A
 {
   int getA() override { return 42; }
 };

+ 14 - 2
Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt

@@ -11,7 +11,7 @@ get_property(c_known_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
 write_compiler_detection_header(
   FILE "${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h"
   PREFIX TEST
-  COMPILERS GNU Clang AppleClang
+  COMPILERS GNU Clang AppleClang MSVC
   VERSION 3.1
   PROLOG "// something"
   EPILOG "// more"
@@ -64,6 +64,18 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
   list(APPEND false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
 endif()
 
+# for msvc the compiler version determines which c++11 features are available.
+# Both variadic templates and delegating constructors support exist in
+# all versions that we write compile headers for.
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND
+    ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_delegating_constructors;")
+  list(APPEND true_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+  list(APPEND true_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+  list(APPEND false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+  list(APPEND false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+endif()
+
 if (CMAKE_C_COMPILER_ID STREQUAL "GNU"
     OR CMAKE_C_COMPILER_ID STREQUAL "Clang"
     OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
@@ -81,7 +93,7 @@ write_compiler_detection_header(
   PREFIX MULTI
   OUTPUT_FILES_VAR multi_files
   OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files/compiler_support"
-  COMPILERS GNU Clang AppleClang
+  COMPILERS GNU Clang AppleClang MSVC
   VERSION 3.1
   FEATURES
     ${cxx_known_features} ${c_known_features}

+ 7 - 2
Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake

@@ -27,8 +27,13 @@ if (NOT CXX_FEATURES)
   run_cmake(NoSupportedCxxFeatures)
   run_cmake(NoSupportedCxxFeaturesGenex)
 else()
-  run_cmake(LinkImplementationFeatureCycle)
-  run_cmake(LinkImplementationFeatureCycleSolved)
+  # compilers such as MSVC have no explicit flags to enable c++11 mode.
+  # Instead they come with all c++11 features implicitly enabled.
+  # So for those types of compilers this tests is not applicable.
+  if(CMAKE_CXX11_STANDARD_COMPILE_OPTION)
+    run_cmake(LinkImplementationFeatureCycle)
+    run_cmake(LinkImplementationFeatureCycleSolved)
+  endif()
 
   if (";${CXX_FEATURES};" MATCHES ";cxx_final;")
     set(RunCMake_TEST_OPTIONS "-DHAVE_FINAL=1")