Skip to content

Commit 63684fe

Browse files
committed
[libc++] Split features.py into multiple files
The features.py file that performs detection of Lit features had grown to be massive, so this patch splits it into smaller chunks which makes it easier to keep things organized.
1 parent cbb3be5 commit 63684fe

File tree

10 files changed

+1002
-921
lines changed

10 files changed

+1002
-921
lines changed

libcxx/utils/libcxx/test/features.py

Lines changed: 0 additions & 920 deletions
This file was deleted.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# ===----------------------------------------------------------------------===##
2+
#
3+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
# See https://llvm.org/LICENSE.txt for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# ===----------------------------------------------------------------------===##
8+
9+
from . import availability, compiler, gdb, libcxx_macros, localization, misc, platform
10+
11+
# Lit features are evaluated in order. Some features depend on other features, so
12+
# we are careful to define them in the correct order. For example, several features
13+
# require the compiler detection to have been performed.
14+
DEFAULT_FEATURES = []
15+
DEFAULT_FEATURES += compiler.features
16+
DEFAULT_FEATURES += libcxx_macros.features
17+
DEFAULT_FEATURES += platform.features
18+
DEFAULT_FEATURES += localization.features
19+
DEFAULT_FEATURES += gdb.features
20+
DEFAULT_FEATURES += misc.features
21+
DEFAULT_FEATURES += availability.features
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# ===----------------------------------------------------------------------===##
2+
#
3+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
# See https://llvm.org/LICENSE.txt for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# ===----------------------------------------------------------------------===##
8+
9+
from libcxx.test.dsl import Feature
10+
from lit.BooleanExpression import BooleanExpression
11+
12+
# Helpers to define correspondances between LLVM versions and vendor system versions.
13+
# Those are used for backdeployment features below, do not use directly in tests.
14+
features = [
15+
Feature(
16+
name="_target-has-llvm-22",
17+
when=lambda cfg: BooleanExpression.evaluate(
18+
"TBD",
19+
cfg.available_features,
20+
),
21+
),
22+
Feature(
23+
name="_target-has-llvm-21",
24+
when=lambda cfg: BooleanExpression.evaluate(
25+
"TBD",
26+
cfg.available_features,
27+
),
28+
),
29+
Feature(
30+
name="_target-has-llvm-20",
31+
when=lambda cfg: BooleanExpression.evaluate(
32+
"_target-has-llvm-21 || target={{.+}}-apple-macosx{{26.[0-9](.\d+)?}}",
33+
cfg.available_features,
34+
),
35+
),
36+
Feature(
37+
name="_target-has-llvm-19",
38+
when=lambda cfg: BooleanExpression.evaluate(
39+
"_target-has-llvm-20 || target={{.+}}-apple-macosx{{15.[4-9](.\d+)?}}",
40+
cfg.available_features,
41+
),
42+
),
43+
Feature(
44+
name="_target-has-llvm-18",
45+
when=lambda cfg: BooleanExpression.evaluate(
46+
"_target-has-llvm-19 || target={{.+}}-apple-macosx{{15.[0-3](.\d+)?}}",
47+
cfg.available_features,
48+
),
49+
),
50+
Feature(
51+
name="_target-has-llvm-17",
52+
when=lambda cfg: BooleanExpression.evaluate(
53+
"_target-has-llvm-18 || target={{.+}}-apple-macosx{{14.[4-9](.\d+)?}}",
54+
cfg.available_features,
55+
),
56+
),
57+
Feature(
58+
name="_target-has-llvm-16",
59+
when=lambda cfg: BooleanExpression.evaluate(
60+
"_target-has-llvm-17 || target={{.+}}-apple-macosx{{14.[0-3](.[0-9]+)?}}",
61+
cfg.available_features,
62+
),
63+
),
64+
Feature(
65+
name="_target-has-llvm-15",
66+
when=lambda cfg: BooleanExpression.evaluate(
67+
"_target-has-llvm-16 || target={{.+}}-apple-macosx{{13.[4-9](.[0-9]+)?}}",
68+
cfg.available_features,
69+
),
70+
),
71+
Feature(
72+
name="_target-has-llvm-14",
73+
when=lambda cfg: BooleanExpression.evaluate(
74+
"_target-has-llvm-15",
75+
cfg.available_features,
76+
),
77+
),
78+
Feature(
79+
name="_target-has-llvm-13",
80+
when=lambda cfg: BooleanExpression.evaluate(
81+
"_target-has-llvm-14 || target={{.+}}-apple-macosx{{13.[0-3](.[0-9]+)?}}",
82+
cfg.available_features,
83+
),
84+
),
85+
Feature(
86+
name="_target-has-llvm-12",
87+
when=lambda cfg: BooleanExpression.evaluate(
88+
"_target-has-llvm-13 || target={{.+}}-apple-macosx{{12.[3-9](.[0-9]+)?}}",
89+
cfg.available_features,
90+
),
91+
),
92+
]
93+
94+
# Define features for back-deployment testing.
95+
#
96+
# These features can be used to XFAIL tests that fail when deployed on (or compiled
97+
# for) an older system. For example, if a test exhibits a bug in the libc++ on a
98+
# particular system version, or if it uses a symbol that is not available on an
99+
# older version of the dylib, it can be marked as XFAIL with these features.
100+
#
101+
# We have two families of Lit features:
102+
#
103+
# The first one is `using-built-library-before-llvm-XYZ`. These features encode the
104+
# fact that the test suite is being *run* against a version of the shared/static library
105+
# that predates LLVM version XYZ. This is useful to represent the use case of compiling
106+
# a program against the latest libc++ but then deploying it and running it on an older
107+
# system with an older version of the (usually shared) library.
108+
#
109+
# This feature is built up using the target triple passed to the compiler and the
110+
# `stdlib=system` Lit feature, which encodes that we're running against the same library
111+
# as described by the target triple.
112+
#
113+
# The second set of features is `availability-<FEATURE>-missing`. This family of Lit
114+
# features encodes the presence of availability markup in the libc++ headers. This is
115+
# useful to check that a test fails specifically when compiled for a given deployment
116+
# target, such as when testing availability markup where we want to make sure that
117+
# using the annotated facility on a deployment target that doesn't support it will fail
118+
# at compile time. This can be achieved by creating a `.verify.cpp` test that checks for
119+
# the right errors and marking the test as `REQUIRES: availability-<FEATURE>-missing`.
120+
#
121+
# This feature is built up using the presence of availability markup detected inside
122+
# __config, the flavor of the library being tested and the target triple passed to the
123+
# compiler.
124+
#
125+
# Note that both families of Lit features are similar but different in important ways.
126+
# For example, tests for availability markup should be expected to produce diagnostics
127+
# regardless of whether we're running against a system library, as long as we're using
128+
# a libc++ flavor that enables availability markup. Similarly, a test could fail when
129+
# run against the system library of an older version of FreeBSD, even though FreeBSD
130+
# doesn't provide availability markup at the time of writing this.
131+
for version in ("12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"):
132+
features.append(
133+
Feature(
134+
name="using-built-library-before-llvm-{}".format(version),
135+
when=lambda cfg, v=version: BooleanExpression.evaluate(
136+
"stdlib=system && !_target-has-llvm-{}".format(v),
137+
cfg.available_features,
138+
),
139+
)
140+
)
141+
142+
features += [
143+
# Tests that require https://wg21.link/P0482 support in the built library
144+
Feature(
145+
name="availability-char8_t_support-missing",
146+
when=lambda cfg: BooleanExpression.evaluate(
147+
"!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-12)",
148+
cfg.available_features,
149+
),
150+
),
151+
# Tests that require std::to_chars(floating-point) in the built library
152+
Feature(
153+
name="availability-fp_to_chars-missing",
154+
when=lambda cfg: BooleanExpression.evaluate(
155+
"!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-14)",
156+
cfg.available_features,
157+
),
158+
),
159+
# Tests that require __libcpp_verbose_abort support in the built library
160+
Feature(
161+
name="availability-verbose_abort-missing",
162+
when=lambda cfg: BooleanExpression.evaluate(
163+
"!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-15)",
164+
cfg.available_features,
165+
),
166+
),
167+
# Tests that require std::pmr support in the built library
168+
Feature(
169+
name="availability-pmr-missing",
170+
when=lambda cfg: BooleanExpression.evaluate(
171+
"!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-16)",
172+
cfg.available_features,
173+
),
174+
),
175+
# Tests that require support for <print> and std::print in <ostream> in the built library.
176+
Feature(
177+
name="availability-print-missing",
178+
when=lambda cfg: BooleanExpression.evaluate(
179+
"!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-18)",
180+
cfg.available_features,
181+
),
182+
),
183+
# Tests that require time zone database support in the built library
184+
Feature(
185+
name="availability-tzdb-missing",
186+
when=lambda cfg: BooleanExpression.evaluate(
187+
"!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-19)",
188+
cfg.available_features,
189+
),
190+
),
191+
# Tests that require std::from_chars(floating-point) in the built library
192+
Feature(
193+
name="availability-fp_from_chars-missing",
194+
when=lambda cfg: BooleanExpression.evaluate(
195+
"!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-20)",
196+
cfg.available_features,
197+
),
198+
),
199+
]
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# ===----------------------------------------------------------------------===##
2+
#
3+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
# See https://llvm.org/LICENSE.txt for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# ===----------------------------------------------------------------------===##
8+
9+
from libcxx.test.dsl import compilerMacros, Feature, AddCompileFlag, AddFeature
10+
11+
_isAnyClang = lambda cfg: "__clang__" in compilerMacros(cfg)
12+
_isAppleClang = lambda cfg: "__apple_build_version__" in compilerMacros(cfg)
13+
_isAnyGCC = lambda cfg: "__GNUC__" in compilerMacros(cfg)
14+
_isClang = lambda cfg: _isAnyClang(cfg) and not _isAppleClang(cfg)
15+
_isGCC = lambda cfg: _isAnyGCC(cfg) and not _isAnyClang(cfg)
16+
_isAnyClangOrGCC = lambda cfg: _isAnyClang(cfg) or _isAnyGCC(cfg)
17+
_isClExe = lambda cfg: not _isAnyClangOrGCC(cfg)
18+
_isMSVC = lambda cfg: "_MSC_VER" in compilerMacros(cfg)
19+
_msvcVersion = lambda cfg: (int(compilerMacros(cfg)["_MSC_VER"]) // 100, int(compilerMacros(cfg)["_MSC_VER"]) % 100)
20+
21+
features = [
22+
# gcc-style-warnings detects compilers that understand -Wno-meow flags, unlike MSVC's compiler driver cl.exe.
23+
Feature(name="gcc-style-warnings", when=_isAnyClangOrGCC),
24+
Feature(name="cl-style-warnings", when=_isClExe),
25+
26+
Feature(name="apple-clang", when=_isAppleClang),
27+
Feature(
28+
name=lambda cfg: "apple-clang-{__clang_major__}".format(**compilerMacros(cfg)),
29+
when=_isAppleClang,
30+
),
31+
Feature(
32+
name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)),
33+
when=_isAppleClang,
34+
),
35+
Feature(
36+
name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)),
37+
when=_isAppleClang,
38+
),
39+
Feature(name="clang", when=_isClang),
40+
Feature(
41+
name=lambda cfg: "clang-{__clang_major__}".format(**compilerMacros(cfg)),
42+
when=_isClang,
43+
),
44+
Feature(
45+
name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)),
46+
when=_isClang,
47+
),
48+
Feature(
49+
name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)),
50+
when=_isClang,
51+
),
52+
# Note: Due to a GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104760), we must disable deprecation warnings
53+
# on GCC or spurious diagnostics are issued.
54+
#
55+
# TODO:
56+
# - Enable -Wplacement-new with GCC.
57+
# - Enable -Wclass-memaccess with GCC.
58+
Feature(
59+
name="gcc",
60+
when=_isGCC,
61+
actions=[
62+
AddCompileFlag("-D_LIBCPP_DISABLE_DEPRECATION_WARNINGS"),
63+
AddCompileFlag("-Wno-placement-new"),
64+
AddCompileFlag("-Wno-class-memaccess"),
65+
AddFeature("GCC-ALWAYS_INLINE-FIXME"),
66+
],
67+
),
68+
Feature(
69+
name=lambda cfg: "gcc-{__GNUC__}".format(**compilerMacros(cfg)), when=_isGCC
70+
),
71+
Feature(
72+
name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}".format(**compilerMacros(cfg)),
73+
when=_isGCC,
74+
),
75+
Feature(
76+
name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}.{__GNUC_PATCHLEVEL__}".format(**compilerMacros(cfg)),
77+
when=_isGCC,
78+
),
79+
Feature(name="msvc", when=_isMSVC),
80+
Feature(name=lambda cfg: "msvc-{}".format(*_msvcVersion(cfg)), when=_isMSVC),
81+
Feature(name=lambda cfg: "msvc-{}.{}".format(*_msvcVersion(cfg)), when=_isMSVC),
82+
]
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# ===----------------------------------------------------------------------===##
2+
#
3+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
# See https://llvm.org/LICENSE.txt for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# ===----------------------------------------------------------------------===##
8+
9+
from libcxx.test.dsl import Feature, AddSubstitution
10+
import shutil
11+
import subprocess
12+
13+
# Detect whether GDB is on the system, has Python scripting and supports
14+
# adding breakpoint commands. If so add a substitution to access it.
15+
def check_gdb(cfg):
16+
gdb_path = shutil.which("gdb")
17+
if gdb_path is None:
18+
return False
19+
20+
# Check that we can set breakpoint commands, which was added in 8.3.
21+
# Using the quit command here means that gdb itself exits, not just
22+
# the "python <...>" command.
23+
test_src = """\
24+
try:
25+
gdb.Breakpoint(\"main\").commands=\"foo\"
26+
except AttributeError:
27+
gdb.execute(\"quit 1\")
28+
gdb.execute(\"quit\")"""
29+
30+
try:
31+
stdout = subprocess.check_output(
32+
[gdb_path, "-ex", "python " + test_src, "--batch"],
33+
stderr=subprocess.DEVNULL,
34+
universal_newlines=True,
35+
)
36+
except subprocess.CalledProcessError:
37+
# We can't set breakpoint commands
38+
return False
39+
40+
# Check we actually ran the Python
41+
return not "Python scripting is not supported" in stdout
42+
43+
44+
features = [
45+
Feature(
46+
name="host-has-gdb-with-python",
47+
when=check_gdb,
48+
actions=[AddSubstitution("%{gdb}", lambda cfg: shutil.which("gdb"))],
49+
)
50+
]

0 commit comments

Comments
 (0)