Browse Source

clang-cl: Add support for C23

Although there is no `cl -std:c23` flag, the underlying Clang compiler
does have a C23 mode we can activate by passing `-std=c23` through a
`clang-cl` wrapper flag.

Also port the fix from commit 30139913e9 (VS: Restore support for mixing
C++23 and C in one target with clang-cl, 2024-12-09, v3.31.3~10^2).

Fixes: #27038
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Co-authored-by: Brad King <brad.king@kitware.com>
release
Yonggang Luo 4 weeks ago
committed by Brad King
parent
commit
9a720d96eb
  1. 4
      .gitlab/ci/configure_windows_clang_common.cmake
  2. 12
      Modules/Compiler/Clang-C.cmake
  3. 13
      Source/cmVisualStudio10TargetGenerator.cxx
  4. 7
      Templates/MSBuild/FlagTables/v143_CL.json
  5. 9
      Tests/CompileFeatures/CMakeLists.txt

4
.gitlab/ci/configure_windows_clang_common.cmake

@ -2,8 +2,8 @@ if("$ENV{CMAKE_CI_BUILD_NAME}" MATCHES "(^|_)gnu(_|$)")
set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23;26" CACHE STRING "")
else()
# FIXME: Implement C23 support for clang-cl.
set(CMake_TEST_C_STANDARDS "90;99;11;17" CACHE STRING "")
# Testing for clang-cl.
set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23" CACHE STRING "")
endif()

12
Modules/Compiler/Clang-C.cmake

@ -78,6 +78,18 @@ else()
endif()
set(CMAKE_C_STANDARD_LATEST 17)
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 18.0)
# This version of clang-cl does not have a -std:c23 flag.
# Pass the standard through to the underlying clang directly.
# Note that cmVisualStudio10TargetGenerator::ComputeClOptions
# has a special case to map this back to -std:clatest in .vcxproj
# files that also have CXX sources.
set(CMAKE_C23_STANDARD_COMPILE_OPTION "-clang:-std=c23")
set(CMAKE_C23_EXTENSION_COMPILE_OPTION "-clang:-std=c23")
set(CMAKE_C_STANDARD_LATEST 23)
endif()
endif()
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 2.1)

13
Source/cmVisualStudio10TargetGenerator.cxx

@ -3553,6 +3553,19 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
flagsC, this->GeneratorTarget, cmBuildStep::Compile, "C", configName);
this->LocalGenerator->AddCompileOptions(flagsC, this->GeneratorTarget, "C",
configName);
// Modules/Compiler/Clang-C.cmake has a special case for clang-cl versions
// that do not have a -std:c23 flag to pass the standard through to the
// underlying clang directly. Unfortunately that flag applies to all
// sources in a single .vcxproj file, so if we have CXX sources too then
// we cannot use it. Map it back to -std:clatest, even though that might
// enable a different C level, so it does not apply to CXX sources.
static std::string const kClangStdC23 = "-clang:-std=c23";
std::string::size_type p = flagsC.find(kClangStdC23);
if (p != std::string::npos) {
flagsC.replace(p, kClangStdC23.size(), "-std:clatest");
}
Options optC(this->LocalGenerator, Options::Compiler,
gg->GetClFlagTable());
optC.Parse(flagsC);

7
Templates/MSBuild/FlagTables/v143_CL.json

@ -524,6 +524,13 @@
"value": "stdc17",
"flags": []
},
{
"name": "LanguageStandard_C",
"switch": "std:clatest",
"comment": "Preview - Features from the Latest C Working Draft",
"value": "stdclatest",
"flags": []
},
{
"name": "PrecompiledHeader",
"switch": "Yc",

9
Tests/CompileFeatures/CMakeLists.txt

@ -37,6 +37,15 @@ if(("23" IN_LIST CMake_TEST_CXX_STANDARDS OR CMAKE_CXX23_STANDARD_COMPILE_OPTION
target_compile_features(test_cxx_std_23_with_c_std_11 PRIVATE cxx_std_23 c_std_11)
endif()
if(("23" IN_LIST CMake_TEST_C_STANDARDS OR CMAKE_C23_STANDARD_COMPILE_OPTION)
AND ("17" IN_LIST CMake_TEST_CXX_STANDARDS OR CMAKE_CXX17_STANDARD_COMPILE_OPTION)
# FIXME: "clang-cl -stc:clatest" does not enable C23.
AND NOT CMAKE_GENERATOR MATCHES "Visual Studio"
)
add_library(test_c_std_23_with_cxx_std_17 OBJECT c_std_23.c cxx_std_17.cpp)
target_compile_features(test_c_std_23_with_cxx_std_17 PRIVATE c_std_23 cxx_std_17)
endif()
macro(run_test feature lang)
if (${feature} IN_LIST CMAKE_${lang}_COMPILE_FEATURES)
add_library(test_${feature} OBJECT ${feature}.${ext_${lang}})

Loading…
Cancel
Save