Browse Source

Merge topic 'clang-cl-c23' into release-4.1

9a720d96eb clang-cl: Add support for C23

Acked-by: Kitware Robot <[email protected]>
Reviewed-by: Raul Tambre <[email protected]>
Acked-by: Raul Tambre <[email protected]>
Merge-request: !10916
Brad King 4 months ago
parent
commit
2e76b79d80

+ 2 - 2
.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 - 0
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 - 0
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 - 0
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 - 0
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}})