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