Commit ae1a6815 authored by Brad King's avatar Brad King

Features: Add infrastructure for C++ 17 language standard

Issue: #16468
parent 684e4d20
Pipeline #36902 passed with stage
......@@ -23,6 +23,9 @@ The features known to this version of CMake are:
``cxx_std_14``
Compiler mode is aware of C++ 14.
``cxx_std_17``
Compiler mode is aware of C++ 17.
``cxx_aggregate_default_initializers``
Aggregate default initializers, as defined in N3605_.
......
......@@ -8,7 +8,7 @@ to build this target. For some compilers, this results in adding a
flag such as ``-std=gnu++11`` to the compile line. For compilers that
have no notion of a standard level, such as MSVC, this has no effect.
Supported values are ``98``, ``11`` and ``14``.
Supported values are ``98``, ``11``, ``14``, and ``17``.
If the value requested does not result in a compile flag being added for
the compiler in use, a previous standard flag will be added instead. This
......
......@@ -14,7 +14,9 @@ char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
@CMAKE_CUDA_COMPILER_ID_ERROR_FOR_TEST@
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
#if __cplusplus >= 201402L
#if __cplusplus > 201402L
"17"
#elif __cplusplus >= 201402L
"14"
#elif __cplusplus >= 201103L
"11"
......
......@@ -8,6 +8,7 @@ set(CMAKE_CXX_COMPILE_FEATURES "@CMAKE_CXX_COMPILE_FEATURES@")
set(CMAKE_CXX98_COMPILE_FEATURES "@CMAKE_CXX98_COMPILE_FEATURES@")
set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
set(CMAKE_CXX14_COMPILE_FEATURES "@CMAKE_CXX14_COMPILE_FEATURES@")
set(CMAKE_CXX17_COMPILE_FEATURES "@CMAKE_CXX17_COMPILE_FEATURES@")
set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
......
......@@ -28,7 +28,9 @@ char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
@CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST@
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
#if __cplusplus >= 201402L
#if __cplusplus > 201402L
"17"
#elif __cplusplus >= 201402L
"14"
#elif __cplusplus >= 201103L
"11"
......
......@@ -48,6 +48,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CXX98_COMPILE_FEATURES)
set(CMAKE_CXX11_COMPILE_FEATURES)
set(CMAKE_CXX14_COMPILE_FEATURES)
set(CMAKE_CXX17_COMPILE_FEATURES)
include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
......@@ -58,6 +59,9 @@ function(cmake_determine_compile_features lang)
return()
endif()
if (CMAKE_CXX14_COMPILE_FEATURES AND CMAKE_CXX17_COMPILE_FEATURES)
list(REMOVE_ITEM CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES})
endif()
if (CMAKE_CXX11_COMPILE_FEATURES AND CMAKE_CXX14_COMPILE_FEATURES)
list(REMOVE_ITEM CMAKE_CXX14_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES})
endif()
......@@ -70,6 +74,7 @@ function(cmake_determine_compile_features lang)
${CMAKE_CXX98_COMPILE_FEATURES}
${CMAKE_CXX11_COMPILE_FEATURES}
${CMAKE_CXX14_COMPILE_FEATURES}
${CMAKE_CXX17_COMPILE_FEATURES}
)
endif()
......@@ -77,6 +82,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CXX98_COMPILE_FEATURES ${CMAKE_CXX98_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX14_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES} PARENT_SCOPE)
message(STATUS "Detecting ${lang} compile features - done")
endif()
......
......@@ -10,6 +10,7 @@ macro(cmake_record_cxx_compile_features)
cxx_std_98
cxx_std_11
cxx_std_14
cxx_std_17
)
_record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
endif()
......
......@@ -1470,6 +1470,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
static std::map<std::string, std::vector<std::string> > langStdMap;
if (langStdMap.empty()) {
// Maintain sorted order, most recent first.
langStdMap["CXX"].push_back("17");
langStdMap["CXX"].push_back("14");
langStdMap["CXX"].push_back("11");
langStdMap["CXX"].push_back("98");
......
......@@ -4064,7 +4064,7 @@ static const char* const CXX_FEATURES[] = { CM_NULLPTR FOR_EACH_CXX_FEATURE(
#undef FEATURE_STRING
static const char* const C_STANDARDS[] = { "90", "99", "11" };
static const char* const CXX_STANDARDS[] = { "98", "11", "14" };
static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17" };
bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
const std::string& feature,
......@@ -4297,7 +4297,9 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
bool needCxx98 = false;
bool needCxx11 = false;
bool needCxx14 = false;
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14);
bool needCxx17 = false;
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
needCxx17);
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
if (!existingCxxStandard) {
......@@ -4336,7 +4338,7 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
bool& needCxx98, bool& needCxx11,
bool& needCxx14) const
bool& needCxx14, bool& needCxx17) const
{
if (const char* propCxx98 =
this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
......@@ -4356,6 +4358,12 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
cmSystemTools::ExpandListArgument(propCxx14, props);
needCxx14 = std::find(props.begin(), props.end(), feature) != props.end();
}
if (const char* propCxx17 =
this->GetDefinition("CMAKE_CXX17_COMPILE_FEATURES")) {
std::vector<std::string> props;
cmSystemTools::ExpandListArgument(propCxx17, props);
needCxx17 = std::find(props.begin(), props.end(), feature) != props.end();
}
}
bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
......@@ -4365,8 +4373,10 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
bool needCxx98 = false;
bool needCxx11 = false;
bool needCxx14 = false;
bool needCxx17 = false;
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14);
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
needCxx17);
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
if (existingCxxStandard) {
......@@ -4393,11 +4403,17 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
bool setCxx98 = needCxx98 && !existingCxxStandard;
bool setCxx11 = needCxx11 && !existingCxxStandard;
bool setCxx14 = needCxx14 && !existingCxxStandard;
bool setCxx17 = needCxx17 && !existingCxxStandard;
if (needCxx14 && existingCxxStandard &&
if (needCxx17 && existingCxxStandard &&
existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
cmArrayEnd(CXX_STANDARDS),
cmStrCmp("14"))) {
cmStrCmp("17"))) {
setCxx17 = true;
} else if (needCxx14 && existingCxxStandard &&
existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
cmArrayEnd(CXX_STANDARDS),
cmStrCmp("14"))) {
setCxx14 = true;
} else if (needCxx11 && existingCxxStandard &&
existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
......@@ -4411,7 +4427,10 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
setCxx98 = true;
}
if (setCxx14) {
if (setCxx17) {
target->SetProperty("CXX_STANDARD", "17");
target->SetProperty("CUDA_STANDARD", "17");
} else if (setCxx14) {
target->SetProperty("CXX_STANDARD", "14");
target->SetProperty("CUDA_STANDARD", "14");
} else if (setCxx11) {
......
......@@ -905,7 +905,8 @@ private:
void CheckNeededCLanguage(const std::string& feature, bool& needC90,
bool& needC99, bool& needC11) const;
void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
bool& needCxx11, bool& needCxx14) const;
bool& needCxx11, bool& needCxx14,
bool& needCxx17) const;
bool HaveCStandardAvailable(cmTarget const* target,
const std::string& feature) const;
......
......@@ -549,6 +549,7 @@ private:
F(cxx_std_98) \
F(cxx_std_11) \
F(cxx_std_14) \
F(cxx_std_17) \
F(cxx_aggregate_default_initializers) \
F(cxx_alias_templates) \
F(cxx_alignas) \
......
......@@ -28,7 +28,7 @@ foreach(feature ${c_features})
run_test(${feature} C)
endforeach()
get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
list(REMOVE_ITEM cxx_features cxx_std_98 cxx_std_11 cxx_std_14)
list(REMOVE_ITEM cxx_features cxx_std_98 cxx_std_11 cxx_std_14 cxx_std_17)
foreach(feature ${cxx_features})
run_test(${feature} CXX)
endforeach()
......@@ -268,6 +268,7 @@ if (CMAKE_CXX_COMPILE_FEATURES)
if (std_flag_idx EQUAL -1)
add_executable(default_dialect default_dialect.cpp)
target_compile_definitions(default_dialect PRIVATE
DEFAULT_CXX17=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},17>
DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
DEFAULT_CXX98=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},98>
......
......@@ -2,7 +2,11 @@
template <long l>
struct Outputter;
#if DEFAULT_CXX14
#if DEFAULT_CXX17
#if __cplusplus <= 201402L
Outputter<__cplusplus> o;
#endif
#elif DEFAULT_CXX14
#if __cplusplus != 201402L
Outputter<__cplusplus> o;
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment