[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