forked from OSchip/llvm-project
[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
This commit is contained in:
parent
e92d2b80c6
commit
c2c68a5940
|
@ -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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"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 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
|
||||
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 @@ test_types = {
|
|||
# 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 @@ test_types = {
|
|||
# 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()
|
||||
|
|
Loading…
Reference in New Issue