Commit 7fe580a3 authored by Brad King's avatar Brad King

Features: Add infrastructure for C++ 20 language standard

Issue: #17849
parent 1b328e09
......@@ -26,6 +26,9 @@ The features known to this version of CMake are:
``cxx_std_17``
Compiler mode is aware of C++ 17.
``cxx_std_20``
Compiler mode is aware of C++ 20.
``cxx_aggregate_default_initializers``
Aggregate default initializers, as defined in N3605_.
......
......@@ -9,7 +9,7 @@ flag such as ``-std=gnu++11`` to the compile line. For compilers that
have no notion of a standard level, such as Microsoft Visual C++ before
2015 Update 3, this has no effect.
Supported values are ``98``, ``11``, ``14``, and ``17``.
Supported values are ``98``, ``11``, ``14``, ``17``, and ``20``.
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
......
......@@ -17,7 +17,9 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
@CMAKE_CUDA_COMPILER_ID_ERROR_FOR_TEST@
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
#if __cplusplus > 201402L
#if __cplusplus > 201703L
"20"
#elif __cplusplus >= 201703L
"17"
#elif __cplusplus >= 201402L
"14"
......
......@@ -10,6 +10,7 @@ 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_CXX20_COMPILE_FEATURES "@CMAKE_CXX20_COMPILE_FEATURES@")
set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
......
......@@ -34,7 +34,9 @@ char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
#if CXX_STD > 201402L
#if CXX_STD > 201703L
"20"
#elif CXX_STD >= 201703L
"17"
#elif CXX_STD >= 201402L
"14"
......
......@@ -49,6 +49,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CXX11_COMPILE_FEATURES)
set(CMAKE_CXX14_COMPILE_FEATURES)
set(CMAKE_CXX17_COMPILE_FEATURES)
set(CMAKE_CXX20_COMPILE_FEATURES)
include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
......@@ -59,6 +60,9 @@ function(cmake_determine_compile_features lang)
return()
endif()
if (CMAKE_CXX17_COMPILE_FEATURES AND CMAKE_CXX20_COMPILE_FEATURES)
list(REMOVE_ITEM CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES})
endif()
if (CMAKE_CXX14_COMPILE_FEATURES AND CMAKE_CXX17_COMPILE_FEATURES)
list(REMOVE_ITEM CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES})
endif()
......@@ -75,6 +79,7 @@ function(cmake_determine_compile_features lang)
${CMAKE_CXX11_COMPILE_FEATURES}
${CMAKE_CXX14_COMPILE_FEATURES}
${CMAKE_CXX17_COMPILE_FEATURES}
${CMAKE_CXX20_COMPILE_FEATURES}
)
endif()
......@@ -83,6 +88,7 @@ function(cmake_determine_compile_features lang)
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)
set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE)
message(STATUS "Detecting ${lang} compile features - done")
endif()
......
......@@ -78,6 +78,9 @@ endmacro()
# Define to allow compile features to be automatically determined
macro(cmake_record_cxx_compile_features)
set(_result 0)
if(_result EQUAL 0 AND DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION)
_record_compiler_features_cxx(20)
endif()
if(_result EQUAL 0 AND DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION)
_record_compiler_features_cxx(17)
endif()
......
......@@ -49,6 +49,8 @@ else()
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
endif()
if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
......
......@@ -29,6 +29,12 @@ if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND
# for meta-features for C++14 and above. Override the default macro
# to avoid doing unnecessary work.
macro(cmake_record_cxx_compile_features)
if (DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION)
list(APPEND CMAKE_CXX20_COMPILE_FEATURES cxx_std_20)
endif()
# The main cmake_record_cxx_compile_features macro makes all
# these conditional on CMAKE_CXX##_STANDARD_COMPILE_OPTION,
# but we can skip the conditions because we set them above.
list(APPEND CMAKE_CXX17_COMPILE_FEATURES cxx_std_17)
list(APPEND CMAKE_CXX14_COMPILE_FEATURES cxx_std_14)
list(APPEND CMAKE_CXX98_COMPILE_FEATURES cxx_std_11) # no flag needed for 11
......@@ -46,6 +52,8 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
# There is no meaningful default for this
set(CMAKE_CXX_STANDARD_DEFAULT "")
......@@ -60,6 +68,7 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
cxx_std_11
cxx_std_14
cxx_std_17
cxx_std_20
)
_record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
endmacro()
......
......@@ -1564,6 +1564,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("20");
langStdMap["CXX"].push_back("17");
langStdMap["CXX"].push_back("14");
langStdMap["CXX"].push_back("11");
......
......@@ -4223,7 +4223,7 @@ static const char* const CXX_FEATURES[] = { 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", "17" };
static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17", "20" };
bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
const std::string& feature,
......@@ -4473,8 +4473,9 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
bool needCxx11 = false;
bool needCxx14 = false;
bool needCxx17 = false;
bool needCxx20 = false;
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
needCxx17);
needCxx17, needCxx20);
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
if (!existingCxxStandard) {
......@@ -4494,7 +4495,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
/* clang-format off */
const char* const* needCxxLevel =
needCxx17 ? &CXX_STANDARDS[3]
needCxx20 ? &CXX_STANDARDS[4]
: needCxx17 ? &CXX_STANDARDS[3]
: needCxx14 ? &CXX_STANDARDS[2]
: needCxx11 ? &CXX_STANDARDS[1]
: needCxx98 ? &CXX_STANDARDS[0]
......@@ -4506,7 +4508,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
bool& needCxx98, bool& needCxx11,
bool& needCxx14, bool& needCxx17) const
bool& needCxx14, bool& needCxx17,
bool& needCxx20) const
{
if (const char* propCxx98 =
this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
......@@ -4532,6 +4535,12 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
cmSystemTools::ExpandListArgument(propCxx17, props);
needCxx17 = std::find(props.begin(), props.end(), feature) != props.end();
}
if (const char* propCxx20 =
this->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")) {
std::vector<std::string> props;
cmSystemTools::ExpandListArgument(propCxx20, props);
needCxx20 = std::find(props.begin(), props.end(), feature) != props.end();
}
}
bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
......@@ -4542,9 +4551,10 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
bool needCxx11 = false;
bool needCxx14 = false;
bool needCxx17 = false;
bool needCxx20 = false;
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
needCxx17);
needCxx17, needCxx20);
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
const char* const* existingCxxLevel = nullptr;
......@@ -4589,7 +4599,8 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
/* clang-format off */
const char* const* needCxxLevel =
needCxx17 ? &CXX_STANDARDS[3]
needCxx20 ? &CXX_STANDARDS[4]
: needCxx17 ? &CXX_STANDARDS[3]
: needCxx14 ? &CXX_STANDARDS[2]
: needCxx11 ? &CXX_STANDARDS[1]
: needCxx98 ? &CXX_STANDARDS[0]
......
......@@ -991,7 +991,7 @@ private:
bool& needC99, bool& needC11) const;
void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
bool& needCxx11, bool& needCxx14,
bool& needCxx17) const;
bool& needCxx17, bool& needCxx20) const;
bool HaveCStandardAvailable(cmTarget const* target,
const std::string& feature) const;
......
......@@ -574,6 +574,7 @@ private:
F(cxx_std_11) \
F(cxx_std_14) \
F(cxx_std_17) \
F(cxx_std_20) \
F(cxx_aggregate_default_initializers) \
F(cxx_alias_templates) \
F(cxx_alignas) \
......
......@@ -280,6 +280,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_CXX20=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},20>
DEFAULT_CXX17=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},17>
DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
......@@ -434,6 +435,7 @@ else()
HAVE_CXX_STD_11=$<COMPILE_FEATURES:cxx_std_11>
HAVE_CXX_STD_14=$<COMPILE_FEATURES:cxx_std_14>
HAVE_CXX_STD_17=$<COMPILE_FEATURES:cxx_std_17>
HAVE_CXX_STD_20=$<COMPILE_FEATURES:cxx_std_20>
)
endif()
......
......@@ -8,7 +8,11 @@ struct Outputter;
#define CXX_STD __cplusplus
#endif
#if DEFAULT_CXX17
#if DEFAULT_CXX20
#if CXX_STD <= 201703L
Outputter<CXX_STD> o;
#endif
#elif DEFAULT_CXX17
#if CXX_STD <= 201402L
Outputter<CXX_STD> 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