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