[libcxx-commits] [libcxx] c2c68a5 - [libc++] Improve generate_feature_test_macro_components.py.

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Sun Apr 4 11:08:58 PDT 2021


Author: Mark de Wever
Date: 2021-04-04T20:08:32+02:00
New Revision: c2c68a5940dcd9c9e910dad78b96ecdec8517011

URL: https://github.com/llvm/llvm-project/commit/c2c68a5940dcd9c9e910dad78b96ecdec8517011
DIFF: https://github.com/llvm/llvm-project/commit/c2c68a5940dcd9c9e910dad78b96ecdec8517011.diff

LOG: [libc++] Improve generate_feature_test_macro_components.py.

This improves the naming of the fields `depends`/`internal_depends`. It
also adds the documentation for this script. The changes are based on
D99290 and its review comments.

Differential Revision: https://reviews.llvm.org/D99615

Added: 
    

Modified: 
    libcxx/utils/generate_feature_test_macro_components.py

Removed: 
    


################################################################################
diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index c3db978f05f7..3dec6d992c3e 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -29,13 +29,45 @@ def add_version_header(tc):
   tc["headers"].append("version")
   return tc
 
+# ================  ============================================================
+# Field             Description
+# ================  ============================================================
+# name              The name of the feature-test macro.
+# values            A dict whose keys are C++ versions and whose values are the
+#                   value of the feature-test macro for that C++ version.
+#                   (TODO: This isn't a very clean model for feature-test
+#                   macros affected by multiple papers.)
+# headers           An array with the headers that should provide the
+#                   feature-test macro.
+# test_suite_guard  An optional string field. When this field is provided,
+#                   `libcxx_guard` must also be provided. This field is used
+#                   only to generate the unit tests for the feature-test macros.
+#                   It can't depend on macros defined in <__config> because the
+#                   `test/std/` parts of the test suite are intended to be
+#                   portable to any C++ standard library implementation, not
+#                   just libc++. It may depend on
+#                    * macros defined by the compiler itself, or
+#                    * macros generated by CMake.
+#                   In some cases we add
+#                   `&& !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM_...)`
+#                   in order to make libc++ pass the tests on OSX; see D94983.
+# libcxx_guard      An optional string field. When this field is provided,
+#                   `test_suite_guard` must also be provided. This field is used
+#                   only to guard the feature-test macro in <version>. It may
+#                   be the same as `test_suite_guard`, or it may depend on
+#                   macros defined in <__config>.
+# unimplemented     An optional Boolean field with the value `True`. This field
+#                   is only used when a feature isn't fully implemented. Once
+#                   you've fully implemented the feature, you should remove
+#                   this field.
+# ================  ============================================================
 feature_test_macros = [ add_version_header(x) for x in [
   {
     "name": "__cpp_lib_addressof_constexpr",
     "values": { "c++17": 201603 },
     "headers": ["memory"],
-    "depends": "TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF)",
+    "test_suite_guard": "TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF)",
   }, {
     "name": "__cpp_lib_allocator_traits_is_always_equal",
     "values": { "c++17": 201411 },
@@ -65,60 +97,60 @@ def add_version_header(tc):
     "name": "__cpp_lib_atomic_flag_test",
     "values": { "c++20": 201907 },
     "headers": ["atomic"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
   }, {
     "name": "__cpp_lib_atomic_float",
     "values": { "c++20": 201711 },
     "headers": ["atomic"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
     "unimplemented": True,
   }, {
     "name": "__cpp_lib_atomic_is_always_lock_free",
     "values": { "c++17": 201603 },
     "headers": ["atomic"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
   }, {
     "name": "__cpp_lib_atomic_lock_free_type_aliases",
     "values": { "c++20": 201907 },
     "headers": ["atomic"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
   }, {
     "name": "__cpp_lib_atomic_ref",
     "values": { "c++20": 201806 },
     "headers": ["atomic"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
     "unimplemented": True,
   }, {
     "name": "__cpp_lib_atomic_shared_ptr",
     "values": { "c++20": 201711 },
     "headers": ["atomic"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
     "unimplemented": True,
   }, {
     "name": "__cpp_lib_atomic_value_initialization",
     "values": { "c++20": 201911 },
     "headers": ["atomic", "memory"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
     "unimplemented": True,
   }, {
     "name": "__cpp_lib_atomic_wait",
     "values": { "c++20": 201907 },
     "headers": ["atomic"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)",
   }, {
     "name": "__cpp_lib_barrier",
     "values": { "c++20": 201907 },
     "headers": ["barrier"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)",
   }, {
     "name": "__cpp_lib_bind_front",
     "values": { "c++20": 201907 },
@@ -154,8 +186,8 @@ def add_version_header(tc):
     "name": "__cpp_lib_char8_t",
     "values": { "c++20": 201811 },
     "headers": ["atomic", "filesystem", "istream", "limits", "locale", "ostream", "string", "string_view"],
-    "depends": "defined(__cpp_char8_t)",
-    "internal_depends": "!defined(_LIBCPP_NO_HAS_CHAR8_T)",
+    "test_suite_guard": "defined(__cpp_char8_t)",
+    "libcxx_guard": "!defined(_LIBCPP_NO_HAS_CHAR8_T)",
   }, {
     "name": "__cpp_lib_chrono",
     "values": { "c++17": 201611 },
@@ -236,8 +268,8 @@ def add_version_header(tc):
     "name": "__cpp_lib_destroying_delete",
     "values": { "c++20": 201806 },
     "headers": ["new"],
-    "depends": "TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L",
-    "internal_depends": "_LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L",
+    "test_suite_guard": "TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L",
+    "libcxx_guard": "_LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L",
   }, {
     "name": "__cpp_lib_enable_shared_from_this",
     "values": { "c++17": 201603 },
@@ -263,8 +295,8 @@ def add_version_header(tc):
     "name": "__cpp_lib_filesystem",
     "values": { "c++17": 201703 },
     "headers": ["filesystem"],
-    "depends": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)",
-    "internal_depends": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)"
+    "test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)",
+    "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)"
   }, {
     "name": "__cpp_lib_format",
     "values": { "c++20": 201907 },
@@ -291,8 +323,8 @@ def add_version_header(tc):
     "name": "__cpp_lib_has_unique_object_representations",
     "values": { "c++17": 201606 },
     "headers": ["type_traits"],
-    "depends": "TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700",
-    "internal_depends": "defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)",
+    "test_suite_guard": "TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700",
+    "libcxx_guard": "defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)",
   }, {
     "name": "__cpp_lib_hypot",
     "values": { "c++17": 201603 },
@@ -330,14 +362,14 @@ def add_version_header(tc):
     "name": "__cpp_lib_is_aggregate",
     "values": { "c++17": 201703 },
     "headers": ["type_traits"],
-    "depends": "TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_IS_AGGREGATE)",
+    "test_suite_guard": "TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_IS_AGGREGATE)",
   }, {
     "name": "__cpp_lib_is_constant_evaluated",
     "values": { "c++20": 201811 },
     "headers": ["type_traits"],
-    "depends": "TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)",
+    "test_suite_guard": "TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)",
   }, {
     "name": "__cpp_lib_is_final",
     "values": { "c++14": 201402 },
@@ -376,15 +408,15 @@ def add_version_header(tc):
     "name": "__cpp_lib_jthread",
     "values": { "c++20": 201911 },
     "headers": ["stop_token", "thread"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)",
     "unimplemented": True,
   }, {
     "name": "__cpp_lib_latch",
     "values": { "c++20": 201907 },
     "headers": ["latch"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)",
   }, {
     "name": "__cpp_lib_launder",
     "values": { "c++17": 201606 },
@@ -417,8 +449,8 @@ def add_version_header(tc):
     "name": "__cpp_lib_math_constants",
     "values": { "c++20": 201907 },
     "headers": ["numbers"],
-    "depends": "defined(__cpp_concepts) && __cpp_concepts >= 201907L",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_CONCEPTS)",
+    "test_suite_guard": "defined(__cpp_concepts) && __cpp_concepts >= 201907L",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_CONCEPTS)",
   }, {
     "name": "__cpp_lib_math_special_functions",
     "values": { "c++17": 201603 },
@@ -496,14 +528,14 @@ def add_version_header(tc):
     "name": "__cpp_lib_semaphore",
     "values": { "c++20": 201907 },
     "headers": ["semaphore"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)",
   }, {
     "name": "__cpp_lib_shared_mutex",
     "values": { "c++17": 201505 },
     "headers": ["shared_mutex"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)",
   }, {
     "name": "__cpp_lib_shared_ptr_arrays",
     "values": { "c++17": 201611 },
@@ -516,8 +548,8 @@ def add_version_header(tc):
     "name": "__cpp_lib_shared_timed_mutex",
     "values": { "c++14": 201402 },
     "headers": ["shared_mutex"],
-    "depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)",
-    "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)",
+    "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)",
+    "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)",
   }, {
     "name": "__cpp_lib_shift",
     "values": { "c++20": 201806 },
@@ -638,6 +670,8 @@ def add_version_header(tc):
 
 assert feature_test_macros == sorted(feature_test_macros, key=lambda tc: tc["name"])
 assert all(tc["headers"] == sorted(tc["headers"]) for tc in feature_test_macros)
+assert all(("libcxx_guard" in tc) == ("test_suite_guard" in tc) for tc in feature_test_macros)
+assert all(all(key in ["name", "values", "headers", "libcxx_guard", "test_suite_guard", "unimplemented"] for key in tc.keys()) for tc in feature_test_macros)
 
 # Map from each header to the Lit annotations that should be used for
 # tests that include that header.
@@ -721,12 +755,11 @@ def produce_macros_definition_for_std(std):
     if std not in tc["values"]:
       continue
     inner_indent = 1
-    if 'depends' in tc.keys():
-      assert 'internal_depends' in tc.keys()
-      result += "# if %s\n" % tc["internal_depends"]
+    if 'test_suite_guard' in tc.keys():
+      result += "# if %s\n" % tc["libcxx_guard"]
       inner_indent += 2
     if get_value_before(tc["values"], std) is not None:
-      assert 'depends' not in tc.keys()
+      assert 'test_suite_guard' not in tc.keys()
       result += "# undef  %s\n" % tc["name"]
     line = "#%sdefine %s" % ((" " * inner_indent), tc["name"])
     line += " " * (indent - len(line))
@@ -735,7 +768,7 @@ def produce_macros_definition_for_std(std):
       line = "// " + line
     result += line
     result += "\n"
-    if 'depends' in tc.keys():
+    if 'test_suite_guard' in tc.keys():
       result += "# endif\n"
   return result.strip()
 
@@ -847,8 +880,8 @@ def produce_version_header():
 # endif
 """,
 
-  "depends": """
-# if {depends}
+  "test_suite_guard": """
+# if {test_suite_guard}
 #   ifndef {name}
 #     error "{name} should be defined in {std}"
 #   endif
@@ -857,7 +890,7 @@ def produce_version_header():
 #   endif
 # else
 #   ifdef {name}
-#     error "{name} should not be defined when {depends} is not defined!"
+#     error "{name} should not be defined when {test_suite_guard} is not defined!"
 #   endif
 # endif
 """,
@@ -897,8 +930,8 @@ def generate_std_test(test_list, std):
       result += test_types["undefined"].format(name=tc["name"], std_first=get_first_std(tc["values"]))
     elif 'unimplemented' in tc.keys():
       result += test_types["unimplemented"].format(name=tc["name"], value=val, std=std)
-    elif "depends" in tc.keys():
-      result += test_types["depends"].format(name=tc["name"], value=val, std=std, depends=tc["depends"])
+    elif "test_suite_guard" in tc.keys():
+      result += test_types["test_suite_guard"].format(name=tc["name"], value=val, std=std, test_suite_guard=tc["test_suite_guard"])
     else:
       result +=  test_types["defined"].format(name=tc["name"], value=val, std=std)
   return result.strip()


        


More information about the libcxx-commits mailing list