From cda233194f9caab8867b2451f3d859080a233d45 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 6 May 2014 11:59:12 +0200 Subject: [PATCH] Features: Record for Clang 3.4 Clang 3.4 supports all features currently known to CMake. --- Modules/Compiler/Clang-C-FeatureTests.cmake | 11 +++ Modules/Compiler/Clang-C.cmake | 36 ++++++++++ Modules/Compiler/Clang-CXX-FeatureTests.cmake | 69 +++++++++++++++++++ Modules/Compiler/Clang-CXX.cmake | 27 +++++++- Modules/WriteCompilerDetectionHeader.cmake | 1 + .../CMakeLists.txt | 5 +- 6 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 Modules/Compiler/Clang-C-FeatureTests.cmake create mode 100644 Modules/Compiler/Clang-CXX-FeatureTests.cmake diff --git a/Modules/Compiler/Clang-C-FeatureTests.cmake b/Modules/Compiler/Clang-C-FeatureTests.cmake new file mode 100644 index 000000000..4a72e87f7 --- /dev/null +++ b/Modules/Compiler/Clang-C-FeatureTests.cmake @@ -0,0 +1,11 @@ + +set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 304") + +set(Clang_C11 "${_cmake_oldestSupported} && __STDC_VERSION__ >= 201112L") +set(_cmake_feature_test_c_static_assert "${Clang_C11}") +set(Clang_C99 "${_cmake_oldestSupported} && __STDC_VERSION__ >= 199901L") +set(_cmake_feature_test_c_restrict "${Clang_C99}") +set(_cmake_feature_test_c_variadic_macros "${Clang_C99}") + +set(Clang_C90 "${_cmake_oldestSupported} && !defined(__STDC_VERSION__)") +set(_cmake_feature_test_c_function_prototypes "${Clang_C90}") diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake index 98fcd0b3f..05d3c0b02 100644 --- a/Modules/Compiler/Clang-C.cmake +++ b/Modules/Compiler/Clang-C.cmake @@ -1,2 +1,38 @@ include(Compiler/Clang) __compiler_clang(C) + +cmake_policy(GET CMP0025 appleClangPolicy) +if(WIN32 OR (APPLE AND NOT appleClangPolicy STREQUAL NEW)) + return() +endif() + +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") + + set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") + + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") +endif() + +set(CMAKE_C_STANDARD_DEFAULT 90) + +macro(cmake_record_c_compile_features) + macro(_get_clang_features std_version list) + record_compiler_features(C "-std=${std_version}" ${list}) + endmacro() + + if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) + _get_clang_features(c11 CMAKE_C11_COMPILE_FEATURES) + if (_result EQUAL 0) + _get_clang_features(c99 CMAKE_C99_COMPILE_FEATURES) + endif() + if (_result EQUAL 0) + _get_clang_features(c90 CMAKE_C90_COMPILE_FEATURES) + endif() + else() + set(_result 0) + endif() +endmacro() diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake new file mode 100644 index 000000000..c4092c447 --- /dev/null +++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake @@ -0,0 +1,69 @@ + +# Reference: http://clang.llvm.org/cxx_status.html +# http://clang.llvm.org/docs/LanguageExtensions.html + +set(testable_features + cxx_alias_templates + cxx_alignas + cxx_attributes + cxx_auto_type + cxx_constexpr + cxx_decltype + cxx_decltype_incomplete_return_types + cxx_default_function_template_args + cxx_defaulted_functions + cxx_delegating_constructors + cxx_deleted_functions + cxx_explicit_conversions + cxx_generalized_initializers + cxx_inheriting_constructors + cxx_lambdas + cxx_local_type_template_args + cxx_noexcept + cxx_nonstatic_member_init + cxx_nullptr + cxx_range_for + cxx_raw_string_literals + cxx_reference_qualified_functions + cxx_rvalue_references + cxx_static_assert + cxx_strong_enums + cxx_thread_local + cxx_unicode_literals + cxx_unrestricted_unions + cxx_user_literals + cxx_variadic_templates +) + +set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 304") + +foreach(feature ${testable_features}) + set(_cmake_feature_test_${feature} "${_cmake_oldestSupported} && __has_feature(${feature})") +endforeach() + +unset(testable_features) + +set(_cmake_feature_test_cxx_trailing_return_types "${_cmake_oldestSupported} && __has_feature(cxx_trailing_return)") +set(_cmake_feature_test_cxx_alignof "${_cmake_oldestSupported} && __has_feature(cxx_alignas)") +set(_cmake_feature_test_cxx_final "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") +set(_cmake_feature_test_cxx_override "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") +set(_cmake_feature_test_cxx_uniform_initialization "${_cmake_oldestSupported} && __has_feature(cxx_generalized_initializers)") +set(_cmake_feature_test_cxx_defaulted_move_initializers "${_cmake_oldestSupported} && __has_feature(cxx_defaulted_functions)") + +# TODO: Should be supported by Clang 3.1 +set(Clang31_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(_cmake_feature_test_cxx_enum_forward_declarations "${Clang31_CXX11}") +set(_cmake_feature_test_cxx_sizeof_member "${Clang31_CXX11}") +# TODO: Should be supported by Clang 2.9 +set(Clang29_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(_cmake_feature_test_cxx_extended_friend_declarations "${Clang29_CXX11}") +set(_cmake_feature_test_cxx_extern_templates "${Clang29_CXX11}") +set(_cmake_feature_test_cxx_func_identifier "${Clang29_CXX11}") +set(_cmake_feature_test_cxx_inline_namespaces "${Clang29_CXX11}") +set(_cmake_feature_test_cxx_long_long_type "${Clang29_CXX11}") +set(_cmake_feature_test_cxx_right_angle_brackets "${Clang29_CXX11}") +set(_cmake_feature_test_cxx_variadic_macros "${Clang29_CXX11}") + +# TODO: Should be supported forever? +set(Clang_CXX98 "${_cmake_oldestSupported} && __cplusplus >= 199711L") +set(_cmake_feature_test_cxx_template_template_parameters "${Clang_CXX98}") diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index 0409c241b..bdb6d69b2 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake @@ -6,7 +6,7 @@ if(NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") endif() cmake_policy(GET CMP0025 appleClangPolicy) -if(APPLE AND NOT appleClangPolicy STREQUAL NEW) +if(WIN32 OR (APPLE AND NOT appleClangPolicy STREQUAL NEW)) return() endif() @@ -22,3 +22,28 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1) set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x") set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x") endif() + +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++1y") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++1y") +endif() + +set(CMAKE_CXX_STANDARD_DEFAULT 98) + +macro(cmake_record_cxx_compile_features) + macro(_get_clang_features std_version list) + record_compiler_features(CXX "-std=${std_version}" ${list}) + endmacro() + + if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) + _get_clang_features(c++1y CMAKE_CXX14_COMPILE_FEATURES) + if (_result EQUAL 0) + _get_clang_features(c++11 CMAKE_CXX11_COMPILE_FEATURES) + endif() + if (_result EQUAL 0) + _get_clang_features(c++98 CMAKE_CXX98_COMPILE_FEATURES) + endif() + else() + set(_result 0) + endif() +endmacro() diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index d3c20372d..d7b89cb38 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -200,6 +200,7 @@ function(write_compiler_detection_header set(compilers GNU + Clang ) foreach(_comp ${_WCD_COMPILERS}) list(FIND compilers ${_comp} idx) diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt index 8dd262e0f..ab0ebc398 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt +++ b/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 + COMPILERS GNU Clang VERSION 3.1 PROLOG "// something" EPILOG "// more" @@ -49,7 +49,8 @@ macro(set_defines target true_defs false_defs) ) endmacro() -if (CMAKE_CXX_COMPILER_ID STREQUAL GNU) +if (CMAKE_CXX_COMPILER_ID STREQUAL GNU + OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) # False for C++98 mode. list(APPEND false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS) list(APPEND false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)