Skip to content

[libc++] Implements the new FTM header test generator. #134542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mordante
Copy link
Member

@mordante mordante commented Apr 6, 2025

This generator has almost identical output to the existing script. Notable differences are

  • conditionally include headers that are not implemented yet
  • removes the synopsis
  • uses 2 spaces indent in # if

There are a few more test macros added that triggered bugs in existing FTM.

@mordante mordante requested a review from a team as a code owner April 6, 2025 15:04
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Apr 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 6, 2025

@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)

Changes

This generator has almost identical output to the existing script. Notable differences are

  • conditionally include not yet implemented headers
  • removes the synopsis
  • uses 2 spaces indent in # if

There are a few more test macros added that triggered bugs in existing FTM.


Patch is 43.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/134542.diff

10 Files Affected:

  • (modified) libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py (+31-5)
  • (added) libcxx/test/libcxx/feature_test_macro/generate_header_test.sh.py (+643)
  • (modified) libcxx/test/libcxx/feature_test_macro/implemented_ftms.sh.py (+8-1)
  • (added) libcxx/test/libcxx/feature_test_macro/implemented_standard_library_headers.sh.py (+32)
  • (modified) libcxx/test/libcxx/feature_test_macro/standard_ftms.sh.py (+13-1)
  • (added) libcxx/test/libcxx/feature_test_macro/standard_library_headers.sh.py (+33)
  • (modified) libcxx/test/libcxx/feature_test_macro/test_data.json (+27-1)
  • (modified) libcxx/test/libcxx/feature_test_macro/version_header.sh.py (+5-3)
  • (modified) libcxx/test/libcxx/feature_test_macro/version_header_implementation.sh.py (+19-3)
  • (modified) libcxx/utils/generate_feature_test_macro_components.py (+281-3)
diff --git a/libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py b/libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py
index 52696d8bc3605..7cf35b2a21d93 100644
--- a/libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py
+++ b/libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py
@@ -27,26 +27,52 @@ def setUp(self):
     def test_implementation(self):
         expected = {
             "__cpp_lib_any": Metadata(
-                headers=["any"], test_suite_guard=None, libcxx_guard=None
+                headers=["any"],
+                available_since="c++17",
+                test_suite_guard=None,
+                libcxx_guard=None,
             ),
             "__cpp_lib_barrier": Metadata(
                 headers=["barrier"],
+                available_since="c++20",
                 test_suite_guard="!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)",
                 libcxx_guard="_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC",
             ),
+            "__cpp_lib_clamp": Metadata(
+                headers=["algorithm"],
+                available_since="c++17",
+                test_suite_guard=None,
+                libcxx_guard=None,
+            ),
             "__cpp_lib_format": Metadata(
-                headers=["format"], test_suite_guard=None, libcxx_guard=None
+                headers=["format"],
+                available_since="c++20",
+                test_suite_guard=None,
+                libcxx_guard=None,
             ),
             "__cpp_lib_parallel_algorithm": Metadata(
                 headers=["algorithm", "numeric"],
+                available_since="c++17",
+                test_suite_guard=None,
+                libcxx_guard=None,
+            ),
+            "__cpp_lib_to_chars": Metadata(
+                headers=["charconv"],
+                available_since="c++17",
                 test_suite_guard=None,
                 libcxx_guard=None,
             ),
             "__cpp_lib_variant": Metadata(
-                headers=["variant"], test_suite_guard=None, libcxx_guard=None
+                headers=["variant"],
+                available_since="c++17",
+                test_suite_guard=None,
+                libcxx_guard=None,
             ),
-            "__cpp_lib_missing_FTM_in_older_standard": Metadata(
-                headers=[], test_suite_guard=None, libcxx_guard=None
+            "__cpp_lib_zz_missing_FTM_in_older_standard": Metadata(
+                headers=[],
+                available_since="c++17",
+                test_suite_guard=None,
+                libcxx_guard=None,
             ),
         }
         self.assertEqual(self.ftm.ftm_metadata, expected)
diff --git a/libcxx/test/libcxx/feature_test_macro/generate_header_test.sh.py b/libcxx/test/libcxx/feature_test_macro/generate_header_test.sh.py
new file mode 100644
index 0000000000000..cca5bae8e7e70
--- /dev/null
+++ b/libcxx/test/libcxx/feature_test_macro/generate_header_test.sh.py
@@ -0,0 +1,643 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+# RUN: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json %t/tests
+
+import os
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+OUTPUT_PATH = sys.argv[3]
+del sys.argv[1:4]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros
+
+
+class Test(unittest.TestCase):
+    def setUp(self):
+        self.ftm = FeatureTestMacros(TEST_DATA)
+        self.maxDiff = None  # This causes the diff to be printed when the test fails
+
+        self.expected = dict(
+            {
+                "algorithm": """\
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by
+// generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <algorithm>
+
+// Test the feature test macros defined by <algorithm>
+
+// clang-format off
+
+#include <algorithm>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+#  ifdef __cpp_lib_clamp
+#    error "__cpp_lib_clamp should not be defined before c++17"
+#  endif
+
+#  ifdef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifndef __cpp_lib_clamp
+#    error "__cpp_lib_clamp should be defined in c++17"
+#  endif
+#  if __cpp_lib_clamp != 201603L
+#    error "__cpp_lib_clamp should have the value 201603L in c++17"
+#  endif
+
+#  ifndef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should be defined in c++17"
+#  endif
+#  if __cpp_lib_parallel_algorithm != 201603L
+#    error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  ifndef __cpp_lib_clamp
+#    error "__cpp_lib_clamp should be defined in c++20"
+#  endif
+#  if __cpp_lib_clamp != 201603L
+#    error "__cpp_lib_clamp should have the value 201603L in c++20"
+#  endif
+
+#  ifndef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should be defined in c++20"
+#  endif
+#  if __cpp_lib_parallel_algorithm != 201603L
+#    error "__cpp_lib_parallel_algorithm should have the value 201603L in c++20"
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  ifndef __cpp_lib_clamp
+#    error "__cpp_lib_clamp should be defined in c++23"
+#  endif
+#  if __cpp_lib_clamp != 201603L
+#    error "__cpp_lib_clamp should have the value 201603L in c++23"
+#  endif
+
+#  ifndef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should be defined in c++23"
+#  endif
+#  if __cpp_lib_parallel_algorithm != 201603L
+#    error "__cpp_lib_parallel_algorithm should have the value 201603L in c++23"
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  ifndef __cpp_lib_clamp
+#    error "__cpp_lib_clamp should be defined in c++26"
+#  endif
+#  if __cpp_lib_clamp != 201603L
+#    error "__cpp_lib_clamp should have the value 201603L in c++26"
+#  endif
+
+#  ifndef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should be defined in c++26"
+#  endif
+#  if __cpp_lib_parallel_algorithm != 201603L
+#    error "__cpp_lib_parallel_algorithm should have the value 201603L in c++26"
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+                "any": """\
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by
+// generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <any>
+
+// Test the feature test macros defined by <any>
+
+// clang-format off
+
+#include <any>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+#  ifdef __cpp_lib_any
+#    error "__cpp_lib_any should not be defined before c++17"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifndef __cpp_lib_any
+#    error "__cpp_lib_any should be defined in c++17"
+#  endif
+#  if __cpp_lib_any != 201606L
+#    error "__cpp_lib_any should have the value 201606L in c++17"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  ifndef __cpp_lib_any
+#    error "__cpp_lib_any should be defined in c++20"
+#  endif
+#  if __cpp_lib_any != 201606L
+#    error "__cpp_lib_any should have the value 201606L in c++20"
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  ifndef __cpp_lib_any
+#    error "__cpp_lib_any should be defined in c++23"
+#  endif
+#  if __cpp_lib_any != 201606L
+#    error "__cpp_lib_any should have the value 201606L in c++23"
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  ifndef __cpp_lib_any
+#    error "__cpp_lib_any should be defined in c++26"
+#  endif
+#  if __cpp_lib_any != 201606L
+#    error "__cpp_lib_any should have the value 201606L in c++26"
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+                "barrier": """\
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by
+// generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// UNSUPPORTED: no-threads
+
+// <barrier>
+
+// Test the feature test macros defined by <barrier>
+
+// clang-format off
+
+#include <barrier>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+#  ifdef __cpp_lib_barrier
+#    error "__cpp_lib_barrier should not be defined before c++20"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifdef __cpp_lib_barrier
+#    error "__cpp_lib_barrier should not be defined before c++20"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)
+#    ifndef __cpp_lib_barrier
+#      error "__cpp_lib_barrier should be defined in c++20"
+#    endif
+#    if __cpp_lib_barrier != 201907L
+#      error "__cpp_lib_barrier should have the value 201907L in c++20"
+#    endif
+#  else
+#    ifdef __cpp_lib_barrier
+#      error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!"
+#    endif
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)
+#    ifndef __cpp_lib_barrier
+#      error "__cpp_lib_barrier should be defined in c++23"
+#    endif
+#    if __cpp_lib_barrier != 201907L
+#      error "__cpp_lib_barrier should have the value 201907L in c++23"
+#    endif
+#  else
+#    ifdef __cpp_lib_barrier
+#      error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!"
+#    endif
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)
+#    ifndef __cpp_lib_barrier
+#      error "__cpp_lib_barrier should be defined in c++26"
+#    endif
+#    if __cpp_lib_barrier != 299900L
+#      error "__cpp_lib_barrier should have the value 299900L in c++26"
+#    endif
+#  else
+#    ifdef __cpp_lib_barrier
+#      error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!"
+#    endif
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+                "charconv": """\
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by
+// generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <charconv>
+
+// Test the feature test macros defined by <charconv>
+
+// clang-format off
+
+#if __has_include(<charconv>)
+#  include <charconv>
+#endif
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+#  ifdef __cpp_lib_to_chars
+#    error "__cpp_lib_to_chars should not be defined before c++17"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_to_chars
+#      error "__cpp_lib_to_chars should be defined in c++17"
+#    endif
+#    if __cpp_lib_to_chars != 201611L
+#      error "__cpp_lib_to_chars should have the value 201611L in c++17"
+#    endif
+#  else
+#    ifdef __cpp_lib_to_chars
+#      error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_to_chars
+#      error "__cpp_lib_to_chars should be defined in c++20"
+#    endif
+#    if __cpp_lib_to_chars != 201611L
+#      error "__cpp_lib_to_chars should have the value 201611L in c++20"
+#    endif
+#  else
+#    ifdef __cpp_lib_to_chars
+#      error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_to_chars
+#      error "__cpp_lib_to_chars should be defined in c++23"
+#    endif
+#    if __cpp_lib_to_chars != 201611L
+#      error "__cpp_lib_to_chars should have the value 201611L in c++23"
+#    endif
+#  else
+#    ifdef __cpp_lib_to_chars
+#      error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_to_chars
+#      error "__cpp_lib_to_chars should be defined in c++26"
+#    endif
+#    if __cpp_lib_to_chars != 201611L
+#      error "__cpp_lib_to_chars should have the value 201611L in c++26"
+#    endif
+#  else
+#    ifdef __cpp_lib_to_chars
+#      error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+                "format": """\
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by
+// generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <format>
+
+// Test the feature test macros defined by <format>
+
+// clang-format off
+
+#include <format>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+#  ifdef __cpp_lib_format
+#    error "__cpp_lib_format should not be defined before c++20"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifdef __cpp_lib_format
+#    error "__cpp_lib_format should not be defined before c++20"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_format
+#      error "__cpp_lib_format should be defined in c++20"
+#    endif
+#    if __cpp_lib_format != 202110L
+#      error "__cpp_lib_format should have the value 202110L in c++20"
+#    endif
+#  else
+#    ifdef __cpp_lib_format
+#      error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_format
+#      error "__cpp_lib_format should be defined in c++23"
+#    endif
+#    if __cpp_lib_format != 202207L
+#      error "__cpp_lib_format should have the value 202207L in c++23"
+#    endif
+#  else
+#    ifdef __cpp_lib_format
+#      error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_format
+#      error "__cpp_lib_format should be defined in c++26"
+#    endif
+#    if __cpp_lib_format != 202311L
+#      error "__cpp_lib_format should have the value 202311L in c++26"
+#    endif
+#  else
+#    ifdef __cpp_lib_format
+#      error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+                "numeric": """\
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by
+// generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <numeric>
+
+// Test the feature test macros defined by <numeric>
+
+// clang-format off
+
+#include <numeric>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+#  ifdef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifndef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should be defined in c++17"
+#  endif
+#  if __cpp_lib_parallel_algorithm != 201603L
+#    error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  ifndef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should be defined in c++20"
+#  endif
+#  if __cpp_lib_parallel_algorithm != 201603L
+#    error "__cpp_lib_parallel_algorithm should have the value 201603L in c++20"
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  ifndef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should be defined in c++23"
+#  endif
+#  if __cpp_lib_parallel_algorithm != 201603L
+#    error "__cpp_lib_parallel_algorithm should have the value 201603L in c++23"
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  ifndef __cpp_lib_parallel_algorithm
+#    error "__cpp_lib_parallel_algorithm should be defined in c++26"
+#  endif
+#  if __cpp_lib_parallel_algorithm != 201603L
+#    error "__cpp_lib_parallel_algorithm should have the value 201603L in c++26"
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+                "variant": """\
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by
+// generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <variant>
+
+// Test the feature test macros defined by <variant>
+
+// clang-format off
+
+#include <variant>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+#  ifdef __cpp_lib_variant
+#    error "__cpp_lib_variant should not be defined before c++17"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifndef __cpp_lib_variant
+#    error "__cpp_lib_variant should be defined in c++17"
+#  endif
+#  if __cpp_lib_variant != 202102L
+#    error "__cpp_lib_variant should have the value 202102L in c++17"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_variant
+#      error "__cpp_lib_variant should be defined in c++20"
+#    endif
+#    if __cpp_lib_variant != 202106L
+#      error "__cpp_lib_variant should have the value 202106L in c++20"
+#    endif
+#  else
+#    ifdef __cpp_lib_variant
+#      error "__cpp_lib_variant should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_variant
+#      error "__cpp_lib_variant should be defined in c++23"
+#    endif
+#    if __cpp_lib_variant != 202106L
+#      error "__cpp_lib_variant should have the value 202106L in c++23"
+#    endif
+#  else
+#    ifdef __cpp_lib_variant
+#      error "__cpp_lib_va...
[truncated]

Copy link

github-actions bot commented Apr 6, 2025

⚠️ Python code formatter, darker found issues in your code. ⚠️

You can test this locally with the following command:
darker --check --diff -r HEAD~1...HEAD libcxx/test/libcxx/feature_test_macro/generate_header_test.sh.py libcxx/test/libcxx/feature_test_macro/standard_library_headers.sh.py libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py libcxx/test/libcxx/feature_test_macro/implemented_ftms.sh.py libcxx/test/libcxx/feature_test_macro/invalid.sh.py libcxx/test/libcxx/feature_test_macro/is_implemented.sh.py libcxx/test/libcxx/feature_test_macro/standard_ftms.sh.py libcxx/test/libcxx/feature_test_macro/std_dialects.sh.py libcxx/test/libcxx/feature_test_macro/version_header.sh.py libcxx/test/libcxx/feature_test_macro/version_header_implementation.sh.py libcxx/utils/generate_feature_test_macro_components.py
View the diff from darker here.
--- utils/generate_feature_test_macro_components.py	2025-05-04 17:37:07.000000 +0000
+++ utils/generate_feature_test_macro_components.py	2025-05-04 17:39:09.803615 +0000
@@ -2083,10 +2083,11 @@
             )
         )
 
     return "\n\n".join(result)
 
+
 #
 # The templates used to create a FTM test file
 #
 
 
@@ -2465,11 +2466,10 @@
                     )
                 )
 
         return result
 
-
     def generate_header_test_ftm(self, std: Std, ftm: Ftm, value: FtmHeaderTest) -> str:
         """Adds a single `ftm` test for C++ `std` based on the status information in `value`.
 
         When std == None this test is generating the TEST_STD_VER < MIN. Where
         MIN is the minimum version that has a FTM defined. (In the real data
@@ -2504,11 +2504,11 @@
             self.generate_header_test_ftm(std, ftm, value)
             for element in data
             for ftm, value in element.items()
         )
 
-    def generate_lit_markup(self, header:str) -> str:
+    def generate_lit_markup(self, header: str) -> str:
         if not header in lit_markup.keys():
             return ""
 
         return "\n".join(f"// {markup}" for markup in lit_markup[header]) + "\n\n"
 
@@ -2578,11 +2578,12 @@
     # Example how to use the new generator to generate the output.
     if False:
         ftm = FeatureTestMacros(
             os.path.join(
                 source_root, "test", "libcxx", "feature_test_macro", "test_data.json"
-            ), headers_not_available
+            ),
+            headers_not_available,
         )
         version_header_path = os.path.join(include_path, "version")
         with open(version_header_path, "w", newline="\n") as f:
             f.write(ftm.version_header)
 

@mordante mordante force-pushed the users/mordante/ftm/is_implemented branch from 14c5af3 to fa5cbcf Compare April 8, 2025 17:41
Base automatically changed from users/mordante/ftm/is_implemented to main April 11, 2025 18:27
This generator has almost identical output to the existing script.
Notable differences are
- conditionally include not yet implemented headers
- removes the synopsis
- uses 2 spaces indent in `# if`

There are a few more test macros added that triggered bugs in existing
FTM.
@mordante mordante force-pushed the users/mordante/ftm/generate_header_tests branch from 00cf2e7 to da82709 Compare April 12, 2025 13:04
This use the status used for the Standard library modules.
continue

result[get_std_number(std)].append(
dict(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to explicitly create a dict here.


for std in self.std_dialects:
if not std in values.keys():
result[get_std_number(std)].append(dict({ftm: None}))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result[get_std_number(std)].append(dict({ftm: None}))
result[get_std_number(std)].append({ftm: None})

@@ -2296,24 +2424,160 @@ def version_header(self) -> str:
)
)

def header_ftm(self, header: str) -> Dict[Std, List[Dict[Ftm, FtmHeaderTest]]]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name of this method is somewhat confusing, since this is really generating test-related data only.

"""

if std == None or value == None:
return ftm_unavailable_in_dialect.format(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try to move the definition of these templates closer to their use. Otherwise we have to jump around quite a bit to understand the function.

None, next(iter(self.header_ftm(header).values()))
),
)
+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would help to introduce variables here to hold the different parts that we're concatenating. Or maybe even

result = ftm_header_test_file_contents.format(...)
result += "".join(...)
result += whatever

Otherwise we end up with one really really large expression grouped together by a single (and subtle) + token.

ftm_header_test_file_dialect_block.format(
pp_if="if",
operator="<",
dialect=self.std_dialects[0][3:],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dialect=self.std_dialects[0][3:],
dialect=get_std_number(self.std_dialects[0]),

Elsewhere too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants