[libc++] Do not set the `availability=XXX` feature when not testing against a system...
[lldb.git] / libcxx / utils / libcxx / test / config.py
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 import locale
10 import os
11 import platform
12 import pkgutil
13 import pipes
14 import re
15 import shlex
16 import shutil
17 import sys
18
19 from libcxx.compiler import CXXCompiler
20 from libcxx.test.target_info import make_target_info
21 from libcxx.test.executor import *
22 from libcxx.test.tracing import *
23 import libcxx.util
24
25 def loadSiteConfig(lit_config, config, param_name, env_name):
26     # We haven't loaded the site specific configuration (the user is
27     # probably trying to run on a test file directly, and either the site
28     # configuration hasn't been created by the build system, or we are in an
29     # out-of-tree build situation).
30     site_cfg = lit_config.params.get(param_name,
31                                      os.environ.get(env_name))
32     if not site_cfg:
33         lit_config.warning('No site specific configuration file found!'
34                            ' Running the tests in the default configuration.')
35     elif not os.path.isfile(site_cfg):
36         lit_config.fatal(
37             "Specified site configuration file does not exist: '%s'" %
38             site_cfg)
39     else:
40         lit_config.note('using site specific configuration at %s' % site_cfg)
41         ld_fn = lit_config.load_config
42
43         # Null out the load_config function so that lit.site.cfg doesn't
44         # recursively load a config even if it tries.
45         # TODO: This is one hell of a hack. Fix it.
46         def prevent_reload_fn(*args, **kwargs):
47             pass
48         lit_config.load_config = prevent_reload_fn
49         ld_fn(config, site_cfg)
50         lit_config.load_config = ld_fn
51
52 # Extract the value of a numeric macro such as __cplusplus or a feature-test
53 # macro.
54 def intMacroValue(token):
55     return int(token.rstrip('LlUu'))
56
57 class Configuration(object):
58     # pylint: disable=redefined-outer-name
59     def __init__(self, lit_config, config):
60         self.lit_config = lit_config
61         self.config = config
62         self.cxx = None
63         self.cxx_is_clang_cl = None
64         self.cxx_stdlib_under_test = None
65         self.project_obj_root = None
66         self.libcxx_src_root = None
67         self.libcxx_obj_root = None
68         self.cxx_library_root = None
69         self.cxx_runtime_root = None
70         self.abi_library_root = None
71         self.link_shared = self.get_lit_bool('enable_shared', default=True)
72         self.debug_build = self.get_lit_bool('debug_build',   default=False)
73         self.exec_env = dict()
74         self.use_target = False
75         self.use_system_cxx_lib = False
76         self.use_clang_verify = False
77         self.long_tests = None
78         self.execute_external = False
79
80     def get_lit_conf(self, name, default=None):
81         val = self.lit_config.params.get(name, None)
82         if val is None:
83             val = getattr(self.config, name, None)
84             if val is None:
85                 val = default
86         return val
87
88     def get_lit_bool(self, name, default=None, env_var=None):
89         def check_value(value, var_name):
90             if value is None:
91                 return default
92             if isinstance(value, bool):
93                 return value
94             if not isinstance(value, str):
95                 raise TypeError('expected bool or string')
96             if value.lower() in ('1', 'true'):
97                 return True
98             if value.lower() in ('', '0', 'false'):
99                 return False
100             self.lit_config.fatal(
101                 "parameter '{}' should be true or false".format(var_name))
102
103         conf_val = self.get_lit_conf(name)
104         if env_var is not None and env_var in os.environ and \
105                 os.environ[env_var] is not None:
106             val = os.environ[env_var]
107             if conf_val is not None:
108                 self.lit_config.warning(
109                     'Environment variable %s=%s is overriding explicit '
110                     '--param=%s=%s' % (env_var, val, name, conf_val))
111             return check_value(val, env_var)
112         return check_value(conf_val, name)
113
114     def get_modules_enabled(self):
115         return self.get_lit_bool('enable_modules',
116                                 default=False,
117                                 env_var='LIBCXX_ENABLE_MODULES')
118
119     def make_static_lib_name(self, name):
120         """Return the full filename for the specified library name"""
121         if self.target_info.is_windows():
122             assert name == 'c++'  # Only allow libc++ to use this function for now.
123             return 'lib' + name + '.lib'
124         else:
125             return 'lib' + name + '.a'
126
127     def configure(self):
128         self.configure_target_info()
129         self.configure_executor()
130         self.configure_use_system_cxx_lib()
131         self.configure_cxx()
132         self.configure_triple()
133         self.configure_deployment()
134         self.configure_src_root()
135         self.configure_obj_root()
136         self.configure_cxx_stdlib_under_test()
137         self.configure_cxx_library_root()
138         self.configure_use_clang_verify()
139         self.configure_use_thread_safety()
140         self.configure_execute_external()
141         self.configure_ccache()
142         self.configure_compile_flags()
143         self.configure_filesystem_compile_flags()
144         self.configure_link_flags()
145         self.configure_env()
146         self.configure_color_diagnostics()
147         self.configure_debug_mode()
148         self.configure_warnings()
149         self.configure_sanitizer()
150         self.configure_coverage()
151         self.configure_modules()
152         self.configure_coroutines()
153         self.configure_substitutions()
154         self.configure_features()
155
156     def print_config_info(self):
157         # Print the final compile and link flags.
158         self.lit_config.note('Using compiler: %s' % self.cxx.path)
159         self.lit_config.note('Using flags: %s' % self.cxx.flags)
160         if self.cxx.use_modules:
161             self.lit_config.note('Using modules flags: %s' %
162                                  self.cxx.modules_flags)
163         self.lit_config.note('Using compile flags: %s'
164                              % self.cxx.compile_flags)
165         if len(self.cxx.warning_flags):
166             self.lit_config.note('Using warnings: %s' % self.cxx.warning_flags)
167         self.lit_config.note('Using link flags: %s' % self.cxx.link_flags)
168         # Print as list to prevent "set([...])" from being printed.
169         self.lit_config.note('Using available_features: %s' %
170                              list(self.config.available_features))
171         show_env_vars = {}
172         for k,v in self.exec_env.items():
173             if k not in os.environ or os.environ[k] != v:
174                 show_env_vars[k] = v
175         self.lit_config.note('Adding environment variables: %r' % show_env_vars)
176         sys.stderr.flush()  # Force flushing to avoid broken output on Windows
177
178     def get_test_format(self):
179         from libcxx.test.format import LibcxxTestFormat
180         return LibcxxTestFormat(
181             self.cxx,
182             self.use_clang_verify,
183             self.execute_external,
184             self.executor,
185             exec_env=self.exec_env)
186
187     def configure_executor(self):
188         exec_str = self.get_lit_conf('executor', "None")
189         te = eval(exec_str)
190         if te:
191             self.lit_config.note("Using executor: %r" % exec_str)
192             if self.lit_config.useValgrind:
193                 # We have no way of knowing where in the chain the
194                 # ValgrindExecutor is supposed to go. It is likely
195                 # that the user wants it at the end, but we have no
196                 # way of getting at that easily.
197                 self.lit_config.fatal("Cannot infer how to create a Valgrind "
198                                       " executor.")
199         else:
200             te = LocalExecutor()
201             if self.lit_config.useValgrind:
202                 te = ValgrindExecutor(self.lit_config.valgrindArgs, te)
203
204         te.target_info = self.target_info
205         self.target_info.executor = te
206
207         self.executor = te
208
209     def configure_target_info(self):
210         self.target_info = make_target_info(self)
211
212     def configure_cxx(self):
213         # Gather various compiler parameters.
214         cxx = self.get_lit_conf('cxx_under_test')
215         self.cxx_is_clang_cl = cxx is not None and \
216                                os.path.basename(cxx) == 'clang-cl.exe'
217         # If no specific cxx_under_test was given, attempt to infer it as
218         # clang++.
219         if cxx is None or self.cxx_is_clang_cl:
220             search_paths = self.config.environment['PATH']
221             if cxx is not None and os.path.isabs(cxx):
222                 search_paths = os.path.dirname(cxx)
223             clangxx = libcxx.util.which('clang++', search_paths)
224             if clangxx:
225                 cxx = clangxx
226                 self.lit_config.note(
227                     "inferred cxx_under_test as: %r" % cxx)
228             elif self.cxx_is_clang_cl:
229                 self.lit_config.fatal('Failed to find clang++ substitution for'
230                                       ' clang-cl')
231         if not cxx:
232             self.lit_config.fatal('must specify user parameter cxx_under_test '
233                                   '(e.g., --param=cxx_under_test=clang++)')
234         self.cxx = CXXCompiler(self, cxx) if not self.cxx_is_clang_cl else \
235                    self._configure_clang_cl(cxx)
236         cxx_type = self.cxx.type
237         if cxx_type is not None:
238             assert self.cxx.version is not None
239             maj_v, min_v, patch_v = self.cxx.version
240             self.config.available_features.add(cxx_type)
241             self.config.available_features.add('%s-%s' % (cxx_type, maj_v))
242             self.config.available_features.add('%s-%s.%s' % (
243                 cxx_type, maj_v, min_v))
244             self.config.available_features.add('%s-%s.%s.%s' % (
245                 cxx_type, maj_v, min_v, patch_v))
246         self.cxx.compile_env = dict(os.environ)
247         # 'CCACHE_CPP2' prevents ccache from stripping comments while
248         # preprocessing. This is required to prevent stripping of '-verify'
249         # comments.
250         self.cxx.compile_env['CCACHE_CPP2'] = '1'
251
252     def _configure_clang_cl(self, clang_path):
253         def _split_env_var(var):
254             return [p.strip() for p in os.environ.get(var, '').split(';') if p.strip()]
255
256         def _prefixed_env_list(var, prefix):
257             from itertools import chain
258             return list(chain.from_iterable((prefix, path) for path in _split_env_var(var)))
259
260         assert self.cxx_is_clang_cl
261         flags = []
262         compile_flags = _prefixed_env_list('INCLUDE', '-isystem')
263         link_flags = _prefixed_env_list('LIB', '-L')
264         for path in _split_env_var('LIB'):
265             self.add_path(self.exec_env, path)
266         return CXXCompiler(self, clang_path, flags=flags,
267                            compile_flags=compile_flags,
268                            link_flags=link_flags)
269
270     def _dump_macros_verbose(self, *args, **kwargs):
271         macros_or_error = self.cxx.dumpMacros(*args, **kwargs)
272         if isinstance(macros_or_error, tuple):
273             cmd, out, err, rc = macros_or_error
274             report = libcxx.util.makeReport(cmd, out, err, rc)
275             report += "Compiler failed unexpectedly when dumping macros!"
276             self.lit_config.fatal(report)
277             return None
278         assert isinstance(macros_or_error, dict)
279         return macros_or_error
280
281     def configure_src_root(self):
282         self.libcxx_src_root = self.get_lit_conf(
283             'libcxx_src_root', os.path.dirname(self.config.test_source_root))
284
285     def configure_obj_root(self):
286         self.project_obj_root = self.get_lit_conf('project_obj_root')
287         self.libcxx_obj_root = self.get_lit_conf('libcxx_obj_root')
288         if not self.libcxx_obj_root and self.project_obj_root is not None:
289             possible_roots = [
290                 os.path.join(self.project_obj_root, 'libcxx'),
291                 os.path.join(self.project_obj_root, 'projects', 'libcxx'),
292                 os.path.join(self.project_obj_root, 'runtimes', 'libcxx'),
293             ]
294             for possible_root in possible_roots:
295                 if os.path.isdir(possible_root):
296                     self.libcxx_obj_root = possible_root
297                     break
298             else:
299                 self.libcxx_obj_root = self.project_obj_root
300
301     def configure_cxx_library_root(self):
302         self.cxx_library_root = self.get_lit_conf('cxx_library_root',
303                                                   self.libcxx_obj_root)
304         self.cxx_runtime_root = self.get_lit_conf('cxx_runtime_root',
305                                                    self.cxx_library_root)
306
307     def configure_use_system_cxx_lib(self):
308         # This test suite supports testing against either the system library or
309         # the locally built one; the former mode is useful for testing ABI
310         # compatibility between the current headers and a shipping dynamic
311         # library.
312         # Default to testing against the locally built libc++ library.
313         self.use_system_cxx_lib = self.get_lit_conf('use_system_cxx_lib')
314         if self.use_system_cxx_lib == 'true':
315             self.use_system_cxx_lib = True
316         elif self.use_system_cxx_lib == 'false':
317             self.use_system_cxx_lib = False
318         elif self.use_system_cxx_lib:
319             assert os.path.isdir(self.use_system_cxx_lib), "the specified use_system_cxx_lib parameter (%s) is not a valid directory" % self.use_system_cxx_lib
320             self.use_system_cxx_lib = os.path.abspath(self.use_system_cxx_lib)
321         self.lit_config.note(
322             "inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib)
323
324     def configure_cxx_stdlib_under_test(self):
325         self.cxx_stdlib_under_test = self.get_lit_conf(
326             'cxx_stdlib_under_test', 'libc++')
327         if self.cxx_stdlib_under_test not in \
328                 ['libc++', 'libstdc++', 'msvc', 'cxx_default']:
329             self.lit_config.fatal(
330                 'unsupported value for "cxx_stdlib_under_test": %s'
331                 % self.cxx_stdlib_under_test)
332         self.config.available_features.add(self.cxx_stdlib_under_test)
333         if self.cxx_stdlib_under_test == 'libstdc++':
334             self.config.available_features.add('libstdc++')
335             # Manually enable the experimental and filesystem tests for libstdc++
336             # if the options aren't present.
337             # FIXME this is a hack.
338             if self.get_lit_conf('enable_experimental') is None:
339                 self.config.enable_experimental = 'true'
340
341     def configure_use_clang_verify(self):
342         '''If set, run clang with -verify on failing tests.'''
343         self.use_clang_verify = self.get_lit_bool('use_clang_verify')
344         if self.use_clang_verify is None:
345             # NOTE: We do not test for the -verify flag directly because
346             #   -verify will always exit with non-zero on an empty file.
347             self.use_clang_verify = self.cxx.isVerifySupported()
348             self.lit_config.note(
349                 "inferred use_clang_verify as: %r" % self.use_clang_verify)
350         if self.use_clang_verify:
351                 self.config.available_features.add('verify-support')
352
353     def configure_use_thread_safety(self):
354         '''If set, run clang with -verify on failing tests.'''
355         has_thread_safety = self.cxx.hasCompileFlag('-Werror=thread-safety')
356         if has_thread_safety:
357             self.cxx.compile_flags += ['-Werror=thread-safety']
358             self.config.available_features.add('thread-safety')
359             self.lit_config.note("enabling thread-safety annotations")
360
361     def configure_execute_external(self):
362         # Choose between lit's internal shell pipeline runner and a real shell.
363         # If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the
364         # default value. Otherwise we ask the target_info.
365         use_lit_shell_default = os.environ.get('LIT_USE_INTERNAL_SHELL')
366         if use_lit_shell_default is not None:
367             use_lit_shell_default = use_lit_shell_default != '0'
368         else:
369             use_lit_shell_default = self.target_info.use_lit_shell_default()
370         # Check for the command line parameter using the default value if it is
371         # not present.
372         use_lit_shell = self.get_lit_bool('use_lit_shell',
373                                           use_lit_shell_default)
374         self.execute_external = not use_lit_shell
375
376     def configure_ccache(self):
377         use_ccache_default = os.environ.get('LIBCXX_USE_CCACHE') is not None
378         use_ccache = self.get_lit_bool('use_ccache', use_ccache_default)
379         if use_ccache:
380             self.cxx.use_ccache = True
381             self.lit_config.note('enabling ccache')
382
383     def add_deployment_feature(self, feature):
384         (arch, name, version) = self.config.deployment
385         self.config.available_features.add('%s=%s-%s' % (feature, arch, name))
386         self.config.available_features.add('%s=%s' % (feature, name))
387         self.config.available_features.add('%s=%s%s' % (feature, name, version))
388
389     def configure_features(self):
390         additional_features = self.get_lit_conf('additional_features')
391         if additional_features:
392             for f in additional_features.split(','):
393                 self.config.available_features.add(f.strip())
394         self.target_info.add_locale_features(self.config.available_features)
395
396         target_platform = self.target_info.platform()
397
398         # Write an "available feature" that combines the triple when
399         # use_system_cxx_lib is enabled. This is so that we can easily write
400         # XFAIL markers for tests that are known to fail with versions of
401         # libc++ as were shipped with a particular triple.
402         if self.use_system_cxx_lib:
403             self.config.available_features.add('with_system_cxx_lib')
404             self.config.available_features.add(
405                 'with_system_cxx_lib=%s' % self.config.target_triple)
406
407             # Add subcomponents individually.
408             target_components = self.config.target_triple.split('-')
409             for component in target_components:
410                 self.config.available_features.add(
411                     'with_system_cxx_lib=%s' % component)
412
413             # Add available features for more generic versions of the target
414             # triple attached to  with_system_cxx_lib.
415             if self.use_deployment:
416                 self.add_deployment_feature('with_system_cxx_lib')
417
418         # Configure the availability feature. Availability is only enabled
419         # with libc++, because other standard libraries do not provide
420         # availability markup.
421         if self.use_deployment and self.cxx_stdlib_under_test == 'libc++' and self.use_system_cxx_lib:
422             self.config.available_features.add('availability')
423             self.add_deployment_feature('availability')
424
425         if self.target_info.is_darwin():
426             self.config.available_features.add('apple-darwin')
427
428         # Insert the platform name into the available features as a lower case.
429         self.config.available_features.add(target_platform)
430
431         # Simulator testing can take a really long time for some of these tests
432         # so add a feature check so we can REQUIRES: long_tests in them
433         self.long_tests = self.get_lit_bool('long_tests')
434         if self.long_tests is None:
435             # Default to running long tests.
436             self.long_tests = True
437             self.lit_config.note(
438                 "inferred long_tests as: %r" % self.long_tests)
439
440         if self.long_tests:
441             self.config.available_features.add('long_tests')
442
443         if not self.get_lit_bool('enable_filesystem', default=True):
444             self.config.available_features.add('c++filesystem-disabled')
445             self.config.available_features.add('dylib-has-no-filesystem')
446
447
448         # Run a compile test for the -fsized-deallocation flag. This is needed
449         # in test/std/language.support/support.dynamic/new.delete
450         if self.cxx.hasCompileFlag('-fsized-deallocation'):
451             self.config.available_features.add('-fsized-deallocation')
452
453         if self.cxx.hasCompileFlag('-faligned-allocation'):
454             self.config.available_features.add('-faligned-allocation')
455         else:
456             # FIXME remove this once more than just clang-4.0 support
457             # C++17 aligned allocation.
458             self.config.available_features.add('no-aligned-allocation')
459
460         if self.cxx.hasCompileFlag('-fdelayed-template-parsing'):
461             self.config.available_features.add('fdelayed-template-parsing')
462
463         if self.get_lit_bool('has_libatomic', False):
464             self.config.available_features.add('libatomic')
465
466         macros = self._dump_macros_verbose()
467         if '__cpp_if_constexpr' not in macros:
468             self.config.available_features.add('libcpp-no-if-constexpr')
469
470         if '__cpp_structured_bindings' not in macros:
471             self.config.available_features.add('libcpp-no-structured-bindings')
472
473         if '__cpp_deduction_guides' not in macros or \
474                 intMacroValue(macros['__cpp_deduction_guides']) < 201611:
475             self.config.available_features.add('libcpp-no-deduction-guides')
476
477         if self.target_info.is_windows():
478             self.config.available_features.add('windows')
479             if self.cxx_stdlib_under_test == 'libc++':
480                 # LIBCXX-WINDOWS-FIXME is the feature name used to XFAIL the
481                 # initial Windows failures until they can be properly diagnosed
482                 # and fixed. This allows easier detection of new test failures
483                 # and regressions. Note: New failures should not be suppressed
484                 # using this feature. (Also see llvm.org/PR32730)
485                 self.config.available_features.add('LIBCXX-WINDOWS-FIXME')
486
487         # Attempt to detect the glibc version by querying for __GLIBC__
488         # in 'features.h'.
489         macros = self.cxx.dumpMacros(flags=['-include', 'features.h'])
490         if isinstance(macros, dict) and '__GLIBC__' in macros:
491             maj_v, min_v = (macros['__GLIBC__'], macros['__GLIBC_MINOR__'])
492             self.config.available_features.add('glibc')
493             self.config.available_features.add('glibc-%s' % maj_v)
494             self.config.available_features.add('glibc-%s.%s' % (maj_v, min_v))
495
496         libcxx_gdb = self.get_lit_conf('libcxx_gdb')
497         if libcxx_gdb and 'NOTFOUND' not in libcxx_gdb:
498             self.config.available_features.add('libcxx_gdb')
499             self.cxx.libcxx_gdb = libcxx_gdb
500
501         # Support Objective-C++ only on MacOS and if the compiler supports it.
502         if self.target_info.platform() == "darwin" and \
503            self.target_info.is_host_macosx() and \
504            self.cxx.hasCompileFlag(["-x", "objective-c++", "-fobjc-arc"]):
505             self.config.available_features.add("objective-c++")
506
507     def configure_compile_flags(self):
508         self.configure_default_compile_flags()
509         # Configure extra flags
510         compile_flags_str = self.get_lit_conf('compile_flags', '')
511         self.cxx.compile_flags += shlex.split(compile_flags_str)
512         if self.target_info.is_windows():
513             # FIXME: Can we remove this?
514             self.cxx.compile_flags += ['-D_CRT_SECURE_NO_WARNINGS']
515             # Required so that tests using min/max don't fail on Windows,
516             # and so that those tests don't have to be changed to tolerate
517             # this insanity.
518             self.cxx.compile_flags += ['-DNOMINMAX']
519         additional_flags = self.get_lit_conf('test_compiler_flags')
520         if additional_flags:
521             self.cxx.compile_flags += shlex.split(additional_flags)
522
523     def configure_default_compile_flags(self):
524         # Try and get the std version from the command line. Fall back to
525         # default given in lit.site.cfg is not present. If default is not
526         # present then force c++11.
527         std = self.get_lit_conf('std')
528         if not std:
529             # Choose the newest possible language dialect if none is given.
530             possible_stds = ['c++2a', 'c++17', 'c++1z', 'c++14', 'c++11',
531                              'c++03']
532             if self.cxx.type == 'gcc':
533                 maj_v, _, _ = self.cxx.version
534                 maj_v = int(maj_v)
535                 if maj_v < 7:
536                     possible_stds.remove('c++1z')
537                     possible_stds.remove('c++17')
538                 # FIXME: How many C++14 tests actually fail under GCC 5 and 6?
539                 # Should we XFAIL them individually instead?
540                 if maj_v <= 6:
541                     possible_stds.remove('c++14')
542             for s in possible_stds:
543                 if self.cxx.hasCompileFlag('-std=%s' % s):
544                     std = s
545                     self.lit_config.note(
546                         'inferred language dialect as: %s' % std)
547                     break
548             if not std:
549                 self.lit_config.fatal(
550                     'Failed to infer a supported language dialect from one of %r'
551                     % possible_stds)
552         self.cxx.compile_flags += ['-std={0}'.format(std)]
553         std_feature = std.replace('gnu++', 'c++')
554         std_feature = std.replace('1z', '17')
555         self.config.available_features.add(std_feature)
556         # Configure include paths
557         self.configure_compile_flags_header_includes()
558         self.target_info.add_cxx_compile_flags(self.cxx.compile_flags)
559         # Configure feature flags.
560         self.configure_compile_flags_exceptions()
561         self.configure_compile_flags_rtti()
562         self.configure_compile_flags_abi_version()
563         enable_32bit = self.get_lit_bool('enable_32bit', False)
564         if enable_32bit:
565             self.cxx.flags += ['-m32']
566         # Use verbose output for better errors
567         self.cxx.flags += ['-v']
568         sysroot = self.get_lit_conf('sysroot')
569         if sysroot:
570             self.cxx.flags += ['--sysroot=' + sysroot]
571         gcc_toolchain = self.get_lit_conf('gcc_toolchain')
572         if gcc_toolchain:
573             self.cxx.flags += ['--gcc-toolchain=' + gcc_toolchain]
574         # NOTE: the _DEBUG definition must preceed the triple check because for
575         # the Windows build of libc++, the forced inclusion of a header requires
576         # that _DEBUG is defined.  Incorrect ordering will result in -target
577         # being elided.
578         if self.target_info.is_windows() and self.debug_build:
579             self.cxx.compile_flags += ['-D_DEBUG']
580         if self.use_target:
581             if not self.cxx.addFlagIfSupported(
582                     ['--target=' + self.config.target_triple]):
583                 self.lit_config.warning('use_target is true but --target is '\
584                         'not supported by the compiler')
585         if self.use_deployment:
586             arch, name, version = self.config.deployment
587             self.cxx.flags += ['-arch', arch]
588             self.cxx.flags += ['-m' + name + '-version-min=' + version]
589
590         # Add includes for support headers used in the tests.
591         support_path = os.path.join(self.libcxx_src_root, 'test/support')
592         self.cxx.compile_flags += ['-I' + support_path]
593
594         # Add includes for the PSTL headers
595         pstl_src_root = self.get_lit_conf('pstl_src_root')
596         pstl_obj_root = self.get_lit_conf('pstl_obj_root')
597         if pstl_src_root is not None and pstl_obj_root is not None:
598             self.cxx.compile_flags += ['-I' + os.path.join(pstl_src_root, 'include')]
599             self.cxx.compile_flags += ['-I' + os.path.join(pstl_obj_root, 'generated_headers')]
600             self.cxx.compile_flags += ['-I' + os.path.join(pstl_src_root, 'test')]
601             self.config.available_features.add('parallel-algorithms')
602
603         # FIXME(EricWF): variant_size.pass.cpp requires a slightly larger
604         # template depth with older Clang versions.
605         self.cxx.addFlagIfSupported('-ftemplate-depth=270')
606
607     def configure_compile_flags_header_includes(self):
608         support_path = os.path.join(self.libcxx_src_root, 'test', 'support')
609         self.configure_config_site_header()
610         if self.cxx_stdlib_under_test != 'libstdc++' and \
611            not self.target_info.is_windows():
612             self.cxx.compile_flags += [
613                 '-include', os.path.join(support_path, 'nasty_macros.h')]
614         if self.cxx_stdlib_under_test == 'msvc':
615             self.cxx.compile_flags += [
616                 '-include', os.path.join(support_path,
617                                          'msvc_stdlib_force_include.h')]
618             pass
619         if self.target_info.is_windows() and self.debug_build and \
620                 self.cxx_stdlib_under_test != 'msvc':
621             self.cxx.compile_flags += [
622                 '-include', os.path.join(support_path,
623                                          'set_windows_crt_report_mode.h')
624             ]
625         cxx_headers = self.get_lit_conf('cxx_headers')
626         if cxx_headers == '' or (cxx_headers is None
627                                  and self.cxx_stdlib_under_test != 'libc++'):
628             self.lit_config.note('using the system cxx headers')
629             return
630         self.cxx.compile_flags += ['-nostdinc++']
631         if cxx_headers is None:
632             cxx_headers = os.path.join(self.libcxx_src_root, 'include')
633         if not os.path.isdir(cxx_headers):
634             self.lit_config.fatal("cxx_headers='%s' is not a directory."
635                                   % cxx_headers)
636         self.cxx.compile_flags += ['-I' + cxx_headers]
637         if self.libcxx_obj_root is not None:
638             cxxabi_headers = os.path.join(self.libcxx_obj_root, 'include',
639                                           'c++build')
640             if os.path.isdir(cxxabi_headers):
641                 self.cxx.compile_flags += ['-I' + cxxabi_headers]
642
643     def configure_config_site_header(self):
644         # Check for a possible __config_site in the build directory. We
645         # use this if it exists.
646         if self.libcxx_obj_root is None:
647             return
648         config_site_header = os.path.join(self.libcxx_obj_root, '__config_site')
649         if not os.path.isfile(config_site_header):
650             return
651         contained_macros = self.parse_config_site_and_add_features(
652             config_site_header)
653         self.lit_config.note('Using __config_site header %s with macros: %r'
654             % (config_site_header, contained_macros))
655         # FIXME: This must come after the call to
656         # 'parse_config_site_and_add_features(...)' in order for it to work.
657         self.cxx.compile_flags += ['-include', config_site_header]
658
659     def parse_config_site_and_add_features(self, header):
660         """ parse_config_site_and_add_features - Deduce and add the test
661             features that that are implied by the #define's in the __config_site
662             header. Return a dictionary containing the macros found in the
663             '__config_site' header.
664         """
665         # Parse the macro contents of __config_site by dumping the macros
666         # using 'c++ -dM -E' and filtering the predefines.
667         predefines = self._dump_macros_verbose()
668         macros = self._dump_macros_verbose(header)
669         feature_macros_keys = set(macros.keys()) - set(predefines.keys())
670         feature_macros = {}
671         for k in feature_macros_keys:
672             feature_macros[k] = macros[k]
673         # We expect the header guard to be one of the definitions
674         assert '_LIBCPP_CONFIG_SITE' in feature_macros
675         del feature_macros['_LIBCPP_CONFIG_SITE']
676         # The __config_site header should be non-empty. Otherwise it should
677         # have never been emitted by CMake.
678         assert len(feature_macros) > 0
679         # FIXME: This is a hack that should be fixed using module maps.
680         # If modules are enabled then we have to lift all of the definitions
681         # in __config_site onto the command line.
682         for m in feature_macros:
683             define = '-D%s' % m
684             if feature_macros[m]:
685                 define += '=%s' % (feature_macros[m])
686             self.cxx.modules_flags += [define]
687         self.cxx.compile_flags += ['-Wno-macro-redefined']
688         # Transform each macro name into the feature name used in the tests.
689         # Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
690         for m in feature_macros:
691             if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS' or \
692                m == '_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT':
693                 continue
694             if m == '_LIBCPP_ABI_VERSION':
695                 self.config.available_features.add('libcpp-abi-version-v%s'
696                     % feature_macros[m])
697                 continue
698             if m == '_LIBCPP_NO_VCRUNTIME':
699                 self.config.available_features.add('libcpp-no-vcruntime')
700                 continue
701             assert m.startswith('_LIBCPP_HAS_') or m.startswith('_LIBCPP_ABI_')
702             m = m.lower()[1:].replace('_', '-')
703             self.config.available_features.add(m)
704         return feature_macros
705
706
707
708     def configure_compile_flags_exceptions(self):
709         enable_exceptions = self.get_lit_bool('enable_exceptions', True)
710         if not enable_exceptions:
711             self.config.available_features.add('libcpp-no-exceptions')
712             self.cxx.compile_flags += ['-fno-exceptions']
713
714     def configure_compile_flags_rtti(self):
715         enable_rtti = self.get_lit_bool('enable_rtti', True)
716         if not enable_rtti:
717             self.config.available_features.add('libcpp-no-rtti')
718             self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
719
720     def configure_compile_flags_abi_version(self):
721         abi_version = self.get_lit_conf('abi_version', '').strip()
722         abi_unstable = self.get_lit_bool('abi_unstable')
723         # Only add the ABI version when it is non-default.
724         # FIXME(EricWF): Get the ABI version from the "__config_site".
725         if abi_version and abi_version != '1':
726           self.cxx.compile_flags += ['-D_LIBCPP_ABI_VERSION=' + abi_version]
727         if abi_unstable:
728           self.config.available_features.add('libcpp-abi-unstable')
729           self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE']
730
731     def configure_filesystem_compile_flags(self):
732         static_env = os.path.join(self.libcxx_src_root, 'test', 'std',
733                                   'input.output', 'filesystems', 'Inputs', 'static_test_env')
734         static_env = os.path.realpath(static_env)
735         assert os.path.isdir(static_env)
736         self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_STATIC_TEST_ROOT="%s"' % static_env]
737
738         dynamic_env = os.path.join(self.config.test_exec_root,
739                                    'filesystem', 'Output', 'dynamic_env')
740         dynamic_env = os.path.realpath(dynamic_env)
741         if not os.path.isdir(dynamic_env):
742             os.makedirs(dynamic_env)
743         self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT="%s"' % dynamic_env]
744         self.exec_env['LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT'] = ("%s" % dynamic_env)
745
746         dynamic_helper = os.path.join(self.libcxx_src_root, 'test', 'support',
747                                       'filesystem_dynamic_test_helper.py')
748         assert os.path.isfile(dynamic_helper)
749
750         self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER="%s %s"'
751                                    % (sys.executable, dynamic_helper)]
752
753
754     def configure_link_flags(self):
755         # Configure library path
756         self.configure_link_flags_cxx_library_path()
757         self.configure_link_flags_abi_library_path()
758
759         # Configure libraries
760         if self.cxx_stdlib_under_test == 'libc++':
761             self.cxx.link_flags += ['-nodefaultlibs']
762             # FIXME: Handle MSVCRT as part of the ABI library handling.
763             if self.target_info.is_windows():
764                 self.cxx.link_flags += ['-nostdlib']
765             self.configure_link_flags_cxx_library()
766             self.configure_link_flags_abi_library()
767             self.configure_extra_library_flags()
768         elif self.cxx_stdlib_under_test == 'libstdc++':
769             self.config.available_features.add('c++experimental')
770             self.cxx.link_flags += ['-lstdc++fs', '-lm', '-pthread']
771         elif self.cxx_stdlib_under_test == 'msvc':
772             # FIXME: Correctly setup debug/release flags here.
773             pass
774         elif self.cxx_stdlib_under_test == 'cxx_default':
775             self.cxx.link_flags += ['-pthread']
776         else:
777             self.lit_config.fatal('invalid stdlib under test')
778
779         link_flags_str = self.get_lit_conf('link_flags', '')
780         self.cxx.link_flags += shlex.split(link_flags_str)
781
782     def configure_link_flags_cxx_library_path(self):
783         if not self.use_system_cxx_lib:
784             if self.cxx_library_root:
785                 self.cxx.link_flags += ['-L' + self.cxx_library_root]
786                 if self.target_info.is_windows() and self.link_shared:
787                     self.add_path(self.cxx.compile_env, self.cxx_library_root)
788             if self.cxx_runtime_root:
789                 if not self.target_info.is_windows():
790                     self.cxx.link_flags += ['-Wl,-rpath,' +
791                                             self.cxx_runtime_root]
792                 elif self.target_info.is_windows() and self.link_shared:
793                     self.add_path(self.exec_env, self.cxx_runtime_root)
794         elif os.path.isdir(str(self.use_system_cxx_lib)):
795             self.cxx.link_flags += ['-L' + self.use_system_cxx_lib]
796             if not self.target_info.is_windows():
797                 self.cxx.link_flags += ['-Wl,-rpath,' +
798                                         self.use_system_cxx_lib]
799             if self.target_info.is_windows() and self.link_shared:
800                 self.add_path(self.cxx.compile_env, self.use_system_cxx_lib)
801         additional_flags = self.get_lit_conf('test_linker_flags')
802         if additional_flags:
803             self.cxx.link_flags += shlex.split(additional_flags)
804
805     def configure_link_flags_abi_library_path(self):
806         # Configure ABI library paths.
807         self.abi_library_root = self.get_lit_conf('abi_library_path')
808         if self.abi_library_root:
809             self.cxx.link_flags += ['-L' + self.abi_library_root]
810             if not self.target_info.is_windows():
811                 self.cxx.link_flags += ['-Wl,-rpath,' + self.abi_library_root]
812             else:
813                 self.add_path(self.exec_env, self.abi_library_root)
814
815     def configure_link_flags_cxx_library(self):
816         libcxx_experimental = self.get_lit_bool('enable_experimental', default=False)
817         if libcxx_experimental:
818             self.config.available_features.add('c++experimental')
819             self.cxx.link_flags += ['-lc++experimental']
820         if self.link_shared:
821             self.cxx.link_flags += ['-lc++']
822         else:
823             cxx_library_root = self.get_lit_conf('cxx_library_root')
824             if cxx_library_root:
825                 libname = self.make_static_lib_name('c++')
826                 abs_path = os.path.join(cxx_library_root, libname)
827                 assert os.path.exists(abs_path) and \
828                        "static libc++ library does not exist"
829                 self.cxx.link_flags += [abs_path]
830             else:
831                 self.cxx.link_flags += ['-lc++']
832
833     def configure_link_flags_abi_library(self):
834         cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
835         if cxx_abi == 'libstdc++':
836             self.cxx.link_flags += ['-lstdc++']
837         elif cxx_abi == 'libsupc++':
838             self.cxx.link_flags += ['-lsupc++']
839         elif cxx_abi == 'libcxxabi':
840             # If the C++ library requires explicitly linking to libc++abi, or
841             # if we're testing libc++abi itself (the test configs are shared),
842             # then link it.
843             testing_libcxxabi = self.get_lit_conf('name', '') == 'libc++abi'
844             if self.target_info.allow_cxxabi_link() or testing_libcxxabi:
845                 libcxxabi_shared = self.get_lit_bool('libcxxabi_shared', default=True)
846                 if libcxxabi_shared:
847                     self.cxx.link_flags += ['-lc++abi']
848                 else:
849                     cxxabi_library_root = self.get_lit_conf('abi_library_path')
850                     if cxxabi_library_root:
851                         libname = self.make_static_lib_name('c++abi')
852                         abs_path = os.path.join(cxxabi_library_root, libname)
853                         self.cxx.link_flags += [abs_path]
854                     else:
855                         self.cxx.link_flags += ['-lc++abi']
856         elif cxx_abi == 'libcxxrt':
857             self.cxx.link_flags += ['-lcxxrt']
858         elif cxx_abi == 'vcruntime':
859             debug_suffix = 'd' if self.debug_build else ''
860             self.cxx.link_flags += ['-l%s%s' % (lib, debug_suffix) for lib in
861                                     ['vcruntime', 'ucrt', 'msvcrt']]
862         elif cxx_abi == 'none' or cxx_abi == 'default':
863             if self.target_info.is_windows():
864                 debug_suffix = 'd' if self.debug_build else ''
865                 self.cxx.link_flags += ['-lmsvcrt%s' % debug_suffix]
866         else:
867             self.lit_config.fatal(
868                 'C++ ABI setting %s unsupported for tests' % cxx_abi)
869
870     def configure_extra_library_flags(self):
871         if self.get_lit_bool('cxx_ext_threads', default=False):
872             self.cxx.link_flags += ['-lc++external_threads']
873         self.target_info.add_cxx_link_flags(self.cxx.link_flags)
874
875     def configure_color_diagnostics(self):
876         use_color = self.get_lit_conf('color_diagnostics')
877         if use_color is None:
878             use_color = os.environ.get('LIBCXX_COLOR_DIAGNOSTICS')
879         if use_color is None:
880             return
881         if use_color != '':
882             self.lit_config.fatal('Invalid value for color_diagnostics "%s".'
883                                   % use_color)
884         color_flag = '-fdiagnostics-color=always'
885         # Check if the compiler supports the color diagnostics flag. Issue a
886         # warning if it does not since color diagnostics have been requested.
887         if not self.cxx.hasCompileFlag(color_flag):
888             self.lit_config.warning(
889                 'color diagnostics have been requested but are not supported '
890                 'by the compiler')
891         else:
892             self.cxx.flags += [color_flag]
893
894     def configure_debug_mode(self):
895         debug_level = self.get_lit_conf('debug_level', None)
896         if not debug_level:
897             return
898         if debug_level not in ['0', '1']:
899             self.lit_config.fatal('Invalid value for debug_level "%s".'
900                                   % debug_level)
901         self.cxx.compile_flags += ['-D_LIBCPP_DEBUG=%s' % debug_level]
902
903     def configure_warnings(self):
904         # Turn on warnings by default for Clang based compilers when C++ >= 11
905         default_enable_warnings = self.cxx.type in ['clang', 'apple-clang'] \
906             and len(self.config.available_features.intersection(
907                 ['c++11', 'c++14', 'c++17', 'c++2a'])) != 0
908         enable_warnings = self.get_lit_bool('enable_warnings',
909                                             default_enable_warnings)
910         self.cxx.useWarnings(enable_warnings)
911         self.cxx.warning_flags += [
912             '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER',
913             '-Wall', '-Wextra', '-Werror'
914         ]
915         if self.cxx.hasWarningFlag('-Wuser-defined-warnings'):
916             self.cxx.warning_flags += ['-Wuser-defined-warnings']
917             self.config.available_features.add('diagnose-if-support')
918         self.cxx.addWarningFlagIfSupported('-Wshadow')
919         self.cxx.addWarningFlagIfSupported('-Wno-unused-command-line-argument')
920         self.cxx.addWarningFlagIfSupported('-Wno-attributes')
921         self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move')
922         self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions')
923         self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals')
924         self.cxx.addWarningFlagIfSupported('-Wno-noexcept-type')
925         self.cxx.addWarningFlagIfSupported('-Wno-aligned-allocation-unavailable')
926         # These warnings should be enabled in order to support the MSVC
927         # team using the test suite; They enable the warnings below and
928         # expect the test suite to be clean.
929         self.cxx.addWarningFlagIfSupported('-Wsign-compare')
930         self.cxx.addWarningFlagIfSupported('-Wunused-variable')
931         self.cxx.addWarningFlagIfSupported('-Wunused-parameter')
932         self.cxx.addWarningFlagIfSupported('-Wunreachable-code')
933         std = self.get_lit_conf('std', None)
934         if std in ['c++98', 'c++03']:
935             # The '#define static_assert' provided by libc++ in C++03 mode
936             # causes an unused local typedef whenever it is used.
937             self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
938
939     def configure_sanitizer(self):
940         san = self.get_lit_conf('use_sanitizer', '').strip()
941         if san:
942             self.target_info.add_sanitizer_features(san, self.config.available_features)
943             # Search for llvm-symbolizer along the compiler path first
944             # and then along the PATH env variable.
945             symbolizer_search_paths = os.environ.get('PATH', '')
946             cxx_path = libcxx.util.which(self.cxx.path)
947             if cxx_path is not None:
948                 symbolizer_search_paths = (
949                     os.path.dirname(cxx_path) +
950                     os.pathsep + symbolizer_search_paths)
951             llvm_symbolizer = libcxx.util.which('llvm-symbolizer',
952                                                 symbolizer_search_paths)
953
954             def add_ubsan():
955                 self.cxx.flags += ['-fsanitize=undefined',
956                                    '-fno-sanitize=float-divide-by-zero',
957                                    '-fno-sanitize-recover=all']
958                 self.exec_env['UBSAN_OPTIONS'] = 'print_stacktrace=1'
959                 self.config.available_features.add('ubsan')
960
961             # Setup the sanitizer compile flags
962             self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
963             if san == 'Address' or san == 'Address;Undefined' or san == 'Undefined;Address':
964                 self.cxx.flags += ['-fsanitize=address']
965                 if llvm_symbolizer is not None:
966                     self.exec_env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer
967                 # FIXME: Turn ODR violation back on after PR28391 is resolved
968                 # https://bugs.llvm.org/show_bug.cgi?id=28391
969                 self.exec_env['ASAN_OPTIONS'] = 'detect_odr_violation=0'
970                 self.config.available_features.add('asan')
971                 self.config.available_features.add('sanitizer-new-delete')
972                 self.cxx.compile_flags += ['-O1']
973                 if san == 'Address;Undefined' or san == 'Undefined;Address':
974                     add_ubsan()
975             elif san == 'Memory' or san == 'MemoryWithOrigins':
976                 self.cxx.flags += ['-fsanitize=memory']
977                 if san == 'MemoryWithOrigins':
978                     self.cxx.compile_flags += [
979                         '-fsanitize-memory-track-origins']
980                 if llvm_symbolizer is not None:
981                     self.exec_env['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer
982                 self.config.available_features.add('msan')
983                 self.config.available_features.add('sanitizer-new-delete')
984                 self.cxx.compile_flags += ['-O1']
985             elif san == 'Undefined':
986                 add_ubsan()
987                 self.cxx.compile_flags += ['-O2']
988             elif san == 'Thread':
989                 self.cxx.flags += ['-fsanitize=thread']
990                 self.config.available_features.add('tsan')
991                 self.config.available_features.add('sanitizer-new-delete')
992             else:
993                 self.lit_config.fatal('unsupported value for '
994                                       'use_sanitizer: {0}'.format(san))
995             san_lib = self.get_lit_conf('sanitizer_library')
996             if san_lib:
997                 self.cxx.link_flags += [
998                     san_lib, '-Wl,-rpath,%s' % os.path.dirname(san_lib)]
999
1000     def configure_coverage(self):
1001         self.generate_coverage = self.get_lit_bool('generate_coverage', False)
1002         if self.generate_coverage:
1003             self.cxx.flags += ['-g', '--coverage']
1004             self.cxx.compile_flags += ['-O0']
1005
1006     def configure_coroutines(self):
1007         if self.cxx.hasCompileFlag('-fcoroutines-ts'):
1008             macros = self._dump_macros_verbose(flags=['-fcoroutines-ts'])
1009             if '__cpp_coroutines' not in macros:
1010                 self.lit_config.warning('-fcoroutines-ts is supported but '
1011                     '__cpp_coroutines is not defined')
1012             # Consider coroutines supported only when the feature test macro
1013             # reflects a recent value.
1014             if intMacroValue(macros['__cpp_coroutines']) >= 201703:
1015                 self.config.available_features.add('fcoroutines-ts')
1016
1017     def configure_modules(self):
1018         modules_flags = ['-fmodules']
1019         if not self.target_info.is_darwin():
1020             modules_flags += ['-Xclang', '-fmodules-local-submodule-visibility']
1021         supports_modules = self.cxx.hasCompileFlag(modules_flags)
1022         enable_modules = self.get_modules_enabled()
1023         if enable_modules and not supports_modules:
1024             self.lit_config.fatal(
1025                 '-fmodules is enabled but not supported by the compiler')
1026         if not supports_modules:
1027             return
1028         self.config.available_features.add('modules-support')
1029         module_cache = os.path.join(self.config.test_exec_root,
1030                                    'modules.cache')
1031         module_cache = os.path.realpath(module_cache)
1032         if os.path.isdir(module_cache):
1033             shutil.rmtree(module_cache)
1034         os.makedirs(module_cache)
1035         self.cxx.modules_flags += modules_flags + \
1036             ['-fmodules-cache-path=' + module_cache]
1037         if enable_modules:
1038             self.config.available_features.add('-fmodules')
1039             self.cxx.useModules()
1040
1041     def configure_substitutions(self):
1042         tool_env = ''
1043         if self.target_info.is_darwin():
1044             # Do not pass DYLD_LIBRARY_PATH to the compiler, linker, etc. as
1045             # these tools are not meant to exercise the just-built libraries.
1046             tool_env += 'DYLD_LIBRARY_PATH="" '
1047
1048         sub = self.config.substitutions
1049         cxx_path = tool_env + pipes.quote(self.cxx.path)
1050         # Configure compiler substitutions
1051         sub.append(('%cxx', cxx_path))
1052         sub.append(('%libcxx_src_root', self.libcxx_src_root))
1053         # Configure flags substitutions
1054         flags_str = ' '.join([pipes.quote(f) for f in self.cxx.flags])
1055         compile_flags_str = ' '.join([pipes.quote(f) for f in self.cxx.compile_flags])
1056         link_flags_str = ' '.join([pipes.quote(f) for f in self.cxx.link_flags])
1057         all_flags = '%s %s %s' % (flags_str, compile_flags_str, link_flags_str)
1058         sub.append(('%flags', flags_str))
1059         sub.append(('%compile_flags', compile_flags_str))
1060         sub.append(('%link_flags', link_flags_str))
1061         sub.append(('%all_flags', all_flags))
1062         if self.cxx.isVerifySupported():
1063             verify_str = ' ' + ' '.join(self.cxx.verify_flags) + ' '
1064             sub.append(('%verify', verify_str))
1065         # Add compile and link shortcuts
1066         compile_str = (cxx_path + ' -o %t.o %s -c ' + flags_str
1067                        + ' ' + compile_flags_str)
1068         link_str = (cxx_path + ' -o %t.exe %t.o ' + flags_str + ' '
1069                     + link_flags_str)
1070         assert type(link_str) is str
1071         build_str = cxx_path + ' -o %t.exe %s ' + all_flags
1072         if self.cxx.use_modules:
1073             sub.append(('%compile_module', compile_str))
1074             sub.append(('%build_module', build_str))
1075         elif self.cxx.modules_flags is not None:
1076             modules_str = ' '.join(self.cxx.modules_flags) + ' '
1077             sub.append(('%compile_module', compile_str + ' ' + modules_str))
1078             sub.append(('%build_module', build_str + ' ' + modules_str))
1079         sub.append(('%compile', compile_str))
1080         sub.append(('%link', link_str))
1081         sub.append(('%build', build_str))
1082         # Configure exec prefix substitutions.
1083         # Configure run env substitution.
1084         codesign_ident = self.get_lit_conf('llvm_codesign_identity', '')
1085         run_py = os.path.join(self.libcxx_src_root, 'utils', 'run.py')
1086         run_str = '%s %s "%s" %%t.exe' % (pipes.quote(sys.executable), \
1087                                           pipes.quote(run_py), codesign_ident)
1088         sub.append(('%run', run_str))
1089         # Configure not program substitutions
1090         not_py = os.path.join(self.libcxx_src_root, 'utils', 'not.py')
1091         not_str = '%s %s ' % (pipes.quote(sys.executable), pipes.quote(not_py))
1092         sub.append(('not ', not_str))
1093         if self.get_lit_conf('libcxx_gdb'):
1094             sub.append(('%libcxx_gdb', self.get_lit_conf('libcxx_gdb')))
1095
1096     def can_use_deployment(self):
1097         # Check if the host is on an Apple platform using clang.
1098         if not self.target_info.is_darwin():
1099             return False
1100         if not self.target_info.is_host_macosx():
1101             return False
1102         if not self.cxx.type.endswith('clang'):
1103             return False
1104         return True
1105
1106     def configure_triple(self):
1107         # Get or infer the target triple.
1108         target_triple = self.get_lit_conf('target_triple')
1109         self.use_target = self.get_lit_bool('use_target', False)
1110         if self.use_target and target_triple:
1111             self.lit_config.warning('use_target is true but no triple is specified')
1112
1113         # Use deployment if possible.
1114         self.use_deployment = not self.use_target and self.can_use_deployment()
1115         if self.use_deployment:
1116             return
1117
1118         # Save the triple (and warn on Apple platforms).
1119         self.config.target_triple = target_triple
1120         if self.use_target and 'apple' in target_triple:
1121             self.lit_config.warning('consider using arch and platform instead'
1122                                     ' of target_triple on Apple platforms')
1123
1124         # If no target triple was given, try to infer it from the compiler
1125         # under test.
1126         if not self.config.target_triple:
1127             target_triple = self.cxx.getTriple()
1128             # Drop sub-major version components from the triple, because the
1129             # current XFAIL handling expects exact matches for feature checks.
1130             # Example: x86_64-apple-darwin14.0.0 -> x86_64-apple-darwin14
1131             # The 5th group handles triples greater than 3 parts
1132             # (ex x86_64-pc-linux-gnu).
1133             target_triple = re.sub(r'([^-]+)-([^-]+)-([^.]+)([^-]*)(.*)',
1134                                    r'\1-\2-\3\5', target_triple)
1135             # linux-gnu is needed in the triple to properly identify linuxes
1136             # that use GLIBC. Handle redhat and opensuse triples as special
1137             # cases and append the missing `-gnu` portion.
1138             if (target_triple.endswith('redhat-linux') or
1139                 target_triple.endswith('suse-linux')):
1140                 target_triple += '-gnu'
1141             self.config.target_triple = target_triple
1142             self.lit_config.note(
1143                 "inferred target_triple as: %r" % self.config.target_triple)
1144
1145     def configure_deployment(self):
1146         assert not self.use_deployment is None
1147         assert not self.use_target is None
1148         if not self.use_deployment:
1149             # Warn about ignored parameters.
1150             if self.get_lit_conf('arch'):
1151                 self.lit_config.warning('ignoring arch, using target_triple')
1152             if self.get_lit_conf('platform'):
1153                 self.lit_config.warning('ignoring platform, using target_triple')
1154             return
1155
1156         assert not self.use_target
1157         assert self.target_info.is_host_macosx()
1158
1159         # Always specify deployment explicitly on Apple platforms, since
1160         # otherwise a platform is picked up from the SDK.  If the SDK version
1161         # doesn't match the system version, tests that use the system library
1162         # may fail spuriously.
1163         arch = self.get_lit_conf('arch')
1164         if not arch:
1165             arch = self.cxx.getTriple().split('-', 1)[0]
1166             self.lit_config.note("inferred arch as: %r" % arch)
1167
1168         inferred_platform, name, version = self.target_info.get_platform()
1169         if inferred_platform:
1170             self.lit_config.note("inferred platform as: %r" % (name + version))
1171         self.config.deployment = (arch, name, version)
1172
1173         # Set the target triple for use by lit.
1174         self.config.target_triple = arch + '-apple-' + name + version
1175         self.lit_config.note(
1176             "computed target_triple as: %r" % self.config.target_triple)
1177
1178         # If we're testing a system libc++ as opposed to the upstream LLVM one,
1179         # take the version of the system libc++ into account to compute which
1180         # features are enabled/disabled. Otherwise, disable availability markup,
1181         # which is not relevant for non-shipped flavors of libc++.
1182         if self.use_system_cxx_lib:
1183             # Dylib support for shared_mutex was added in macosx10.12.
1184             if name == 'macosx' and version in ('10.%s' % v for v in range(7, 12)):
1185                 self.config.available_features.add('dylib-has-no-shared_mutex')
1186                 self.lit_config.note("shared_mutex is not supported by the deployment target")
1187             # Throwing bad_optional_access, bad_variant_access and bad_any_cast is
1188             # supported starting in macosx10.14.
1189             if name == 'macosx' and version in ('10.%s' % v for v in range(7, 14)):
1190                 self.config.available_features.add('dylib-has-no-bad_optional_access')
1191                 self.lit_config.note("throwing bad_optional_access is not supported by the deployment target")
1192
1193                 self.config.available_features.add('dylib-has-no-bad_variant_access')
1194                 self.lit_config.note("throwing bad_variant_access is not supported by the deployment target")
1195
1196                 self.config.available_features.add('dylib-has-no-bad_any_cast')
1197                 self.lit_config.note("throwing bad_any_cast is not supported by the deployment target")
1198             # Filesystem is support on Apple platforms starting with macosx10.15.
1199             if name == 'macosx' and version in ('10.%s' % v for v in range(7, 15)):
1200                 self.config.available_features.add('dylib-has-no-filesystem')
1201                 self.lit_config.note("the deployment target does not support <filesystem>")
1202         else:
1203             self.cxx.flags += ['-D_LIBCPP_DISABLE_AVAILABILITY']
1204
1205     def configure_env(self):
1206         self.target_info.configure_env(self.exec_env)
1207
1208     def add_path(self, dest_env, new_path):
1209         self.target_info.add_path(dest_env, new_path)