# -*- Python -*-

# Configuration file for 'lit' test runner.
# This file contains common rules for various compiler-rt testsuites.
# It is mostly copied from lit.cfg.py used by Clang.
import os
import platform
import re
import subprocess
import json

import lit.formats
import lit.util

# Get shlex.quote if available (added in 3.3), and fall back to pipes.quote if
# it's not available.
try:
  import shlex
  sh_quote = shlex.quote
except:
  import pipes
  sh_quote = pipes.quote

def find_compiler_libdir():
  """
    Returns the path to library resource directory used
    by the compiler.
  """
  if config.compiler_id != 'Clang':
    lit_config.warning(f'Determining compiler\'s runtime directory is not supported for {config.compiler_id}')
    # TODO: Support other compilers.
    return None
  def get_path_from_clang(args, allow_failure):
    clang_cmd = [
      config.clang.strip(),
      f'--target={config.target_triple}',
    ]
    clang_cmd.extend(args)
    path = None
    try:
      result = subprocess.run(
        clang_cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        check=True
      )
      path = result.stdout.decode().strip()
    except subprocess.CalledProcessError as e:
      msg = f'Failed to run {clang_cmd}\nrc:{e.returncode}\nstdout:{e.stdout}\ne.stderr{e.stderr}'
      if allow_failure:
        lit_config.warning(msg)
      else:
        lit_config.fatal(msg)
    return path, clang_cmd

  # Try using `-print-runtime-dir`. This is only supported by very new versions of Clang.
  # so allow failure here.
  runtime_dir, clang_cmd = get_path_from_clang(shlex.split(config.target_cflags)
                                               + ['-print-runtime-dir'],
                                               allow_failure=True)
  if runtime_dir:
    if os.path.exists(runtime_dir):
      return os.path.realpath(runtime_dir)
    # TODO(dliew): This should be a fatal error but it seems to trip the `llvm-clang-win-x-aarch64`
    # bot which is likely misconfigured
    lit_config.warning(
      f'Path reported by clang does not exist: \"{runtime_dir}\". '
      f'This path was found by running {clang_cmd}.'
    )
    return None

  # Fall back for older AppleClang that doesn't support `-print-runtime-dir`
  # Note `-print-file-name=<path to compiler-rt lib>` was broken for Apple
  # platforms so we can't use that approach here (see https://reviews.llvm.org/D101682).
  if config.host_os == 'Darwin':
    lib_dir, _ = get_path_from_clang(['-print-file-name=lib'], allow_failure=False)
    runtime_dir = os.path.join(lib_dir, 'darwin')
    if not os.path.exists(runtime_dir):
      lit_config.fatal(f'Path reported by clang does not exist: {runtime_dir}')
    return os.path.realpath(runtime_dir)

  lit_config.warning('Failed to determine compiler\'s runtime directory')
  return None


# Choose between lit's internal shell pipeline runner and a real shell.  If
# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
if use_lit_shell:
    # 0 is external, "" is default, and everything else is internal.
    execute_external = (use_lit_shell == "0")
else:
    # Otherwise we default to internal on Windows and external elsewhere, as
    # bash on Windows is usually very slow.
    execute_external = (not sys.platform in ['win32'])

# Allow expanding substitutions that are based on other substitutions
config.recursiveExpansionLimit = 10

# Setup test format.
config.test_format = lit.formats.ShTest(execute_external)
if execute_external:
  config.available_features.add('shell')

compiler_id = getattr(config, 'compiler_id', None)
if compiler_id == "Clang":
  if platform.system() != 'Windows':
    config.cxx_mode_flags = ["--driver-mode=g++"]
  else:
    config.cxx_mode_flags = []
  # We assume that sanitizers should provide good enough error
  # reports and stack traces even with minimal debug info.
  config.debug_info_flags = ["-gline-tables-only"]
  if platform.system() == 'Windows':
    # On Windows, use CodeView with column info instead of DWARF. Both VS and
    # windbg do not behave well when column info is enabled, but users have
    # requested it because it makes ASan reports more precise.
    config.debug_info_flags.append("-gcodeview")
    config.debug_info_flags.append("-gcolumn-info")
elif compiler_id == 'GNU':
  config.cxx_mode_flags = ["-x c++"]
  config.debug_info_flags = ["-g"]
else:
  lit_config.fatal("Unsupported compiler id: %r" % compiler_id)
# Add compiler ID to the list of available features.
config.available_features.add(compiler_id)

# When LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=on, the initial value of
# config.compiler_rt_libdir (COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR) has the
# triple as the trailing path component. The value is incorrect for -m32/-m64.
# Adjust config.compiler_rt accordingly.
if config.enable_per_target_runtime_dir:
    if '-m32' in shlex.split(config.target_cflags):
        config.compiler_rt_libdir = re.sub(r'/x86_64(?=-[^/]+$)', '/i386', config.compiler_rt_libdir)
    elif '-m64' in shlex.split(config.target_cflags):
        config.compiler_rt_libdir = re.sub(r'/i386(?=-[^/]+$)', '/x86_64', config.compiler_rt_libdir)

# Ask the compiler for the path to libraries it is going to use. If this
# doesn't match config.compiler_rt_libdir then it means we might be testing the
# compiler's own runtime libraries rather than the ones we just built.
# Warn about about this and handle appropriately.
compiler_libdir = find_compiler_libdir()
if compiler_libdir:
  compiler_rt_libdir_real = os.path.realpath(config.compiler_rt_libdir)
  if compiler_libdir != compiler_rt_libdir_real:
    lit_config.warning(
      'Compiler lib dir != compiler-rt lib dir\n'
      f'Compiler libdir:     "{compiler_libdir}"\n'
      f'compiler-rt libdir:  "{compiler_rt_libdir_real}"')
    if config.test_standalone_build_libs:
      # Use just built runtime libraries, i.e. the the libraries this built just built.
      if not config.test_suite_supports_overriding_runtime_lib_path:
        # Test suite doesn't support this configuration.
        # TODO(dliew): This should be an error but it seems several bots are
        # testing incorrectly and having this as an error breaks them.
        lit_config.warning(
            'COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite '
            'does not support testing the just-built runtime libraries '
            'when the test compiler is configured to use different runtime '
            'libraries. Either modify this test suite to support this test '
            'configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF '
            'to test the runtime libraries included in the compiler instead.'
        )
    else:
      # Use Compiler's resource library directory instead.
      config.compiler_rt_libdir = compiler_libdir
    lit_config.note(f'Testing using libraries in "{config.compiler_rt_libdir}"')

# If needed, add cflag for shadow scale.
if config.asan_shadow_scale != '':
  config.target_cflags += " -mllvm -asan-mapping-scale=" + config.asan_shadow_scale
if config.memprof_shadow_scale != '':
  config.target_cflags += " -mllvm -memprof-mapping-scale=" + config.memprof_shadow_scale

config.environment = dict(os.environ)

# Clear some environment variables that might affect Clang.
possibly_dangerous_env_vars = ['ASAN_OPTIONS', 'DFSAN_OPTIONS', 'LSAN_OPTIONS',
                               'MSAN_OPTIONS', 'UBSAN_OPTIONS',
                               'COMPILER_PATH', 'RC_DEBUG_OPTIONS',
                               'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH',
                               'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH',
                               'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH',
                               'LIBCLANG_TIMING', 'LIBCLANG_OBJTRACKING',
                               'LIBCLANG_LOGGING', 'LIBCLANG_BGPRIO_INDEX',
                               'LIBCLANG_BGPRIO_EDIT', 'LIBCLANG_NOTHREADS',
                               'LIBCLANG_RESOURCE_USAGE',
                               'LIBCLANG_CODE_COMPLETION_LOGGING',
                               'XRAY_OPTIONS']
# Clang/Win32 may refer to %INCLUDE%. vsvarsall.bat sets it.
if platform.system() != 'Windows':
    possibly_dangerous_env_vars.append('INCLUDE')
for name in possibly_dangerous_env_vars:
  if name in config.environment:
    del config.environment[name]

# Tweak PATH to include llvm tools dir.
if (not config.llvm_tools_dir) or (not os.path.exists(config.llvm_tools_dir)):
  lit_config.fatal("Invalid llvm_tools_dir config attribute: %r" % config.llvm_tools_dir)
path = os.path.pathsep.join((config.llvm_tools_dir, config.environment['PATH']))
config.environment['PATH'] = path

# Help MSVS link.exe find the standard libraries.
# Make sure we only try to use it when targetting Windows.
if platform.system() == 'Windows' and '-win' in config.target_triple:
  config.environment['LIB'] = os.environ['LIB']

config.available_features.add(config.host_os.lower())

if config.target_triple.startswith("ppc") or config.target_triple.startswith("powerpc"):
  config.available_features.add("ppc")

if re.match(r'^x86_64.*-linux', config.target_triple):
  config.available_features.add("x86_64-linux")

config.available_features.add("host-byteorder-" + sys.byteorder + "-endian")

if config.have_zlib == "1":
  config.available_features.add("zlib")

# Use ugly construction to explicitly prohibit "clang", "clang++" etc.
# in RUN lines.
config.substitutions.append(
    (' clang', """\n\n*** Do not use 'clangXXX' in tests,
     instead define '%clangXXX' substitution in lit config. ***\n\n""") )

if config.host_os == 'NetBSD':
  nb_commands_dir = os.path.join(config.compiler_rt_src_root,
                                 "test", "sanitizer_common", "netbsd_commands")
  config.netbsd_noaslr_prefix = ('sh ' +
                                 os.path.join(nb_commands_dir, 'run_noaslr.sh'))
  config.netbsd_nomprotect_prefix = ('sh ' +
                                     os.path.join(nb_commands_dir,
                                                  'run_nomprotect.sh'))
  config.substitutions.append( ('%run_nomprotect',
                                config.netbsd_nomprotect_prefix) )
else:
  config.substitutions.append( ('%run_nomprotect', '%run') )

# Copied from libcxx's config.py
def get_lit_conf(name, default=None):
    # Allow overriding on the command line using --param=<name>=<val>
    val = lit_config.params.get(name, None)
    if val is None:
        val = getattr(config, name, None)
        if val is None:
            val = default
    return val

emulator = get_lit_conf('emulator', None)

def get_ios_commands_dir():
  return os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ios_commands")

# Allow tests to be executed on a simulator or remotely.
if emulator:
  config.substitutions.append( ('%run', emulator) )
  config.substitutions.append( ('%env ', "env ") )
  # TODO: Implement `%device_rm` to perform removal of files in the emulator.
  # For now just make it a no-op.
  lit_config.warning('%device_rm is not implemented')
  config.substitutions.append( ('%device_rm', 'echo ') )
  config.compile_wrapper = ""
elif config.host_os == 'Darwin' and config.apple_platform != "osx":
  # Darwin tests can be targetting macOS, a device or a simulator. All devices
  # are declared as "ios", even for iOS derivatives (tvOS, watchOS). Similarly,
  # all simulators are "iossim". See the table below.
  #
  # =========================================================================
  # Target             | Feature set
  # =========================================================================
  # macOS              | darwin
  # iOS device         | darwin, ios
  # iOS simulator      | darwin, ios, iossim
  # tvOS device        | darwin, ios, tvos
  # tvOS simulator     | darwin, ios, iossim, tvos, tvossim
  # watchOS device     | darwin, ios, watchos
  # watchOS simulator  | darwin, ios, iossim, watchos, watchossim
  # =========================================================================

  ios_or_iossim = "iossim" if config.apple_platform.endswith("sim") else "ios"

  config.available_features.add('ios')
  device_id_env = "SANITIZER_" + ios_or_iossim.upper() + "_TEST_DEVICE_IDENTIFIER"
  if ios_or_iossim == "iossim":
    config.available_features.add('iossim')
    if device_id_env not in os.environ:
      lit_config.fatal(
        '{} must be set in the environment when running iossim tests'.format(
          device_id_env))
  if config.apple_platform != "ios" and config.apple_platform != "iossim":
    config.available_features.add(config.apple_platform)

  ios_commands_dir = get_ios_commands_dir()

  run_wrapper = os.path.join(ios_commands_dir, ios_or_iossim + "_run.py")
  env_wrapper = os.path.join(ios_commands_dir, ios_or_iossim + "_env.py")
  compile_wrapper = os.path.join(ios_commands_dir, ios_or_iossim + "_compile.py")
  prepare_script = os.path.join(ios_commands_dir, ios_or_iossim + "_prepare.py")

  if device_id_env in os.environ:
    config.environment[device_id_env] = os.environ[device_id_env]
  config.substitutions.append(('%run', run_wrapper))
  config.substitutions.append(('%env ', env_wrapper + " "))
  # Current implementation of %device_rm uses the run_wrapper to do
  # the work.
  config.substitutions.append(('%device_rm', '{} rm '.format(run_wrapper)))
  config.compile_wrapper = compile_wrapper

  try:
    prepare_output = subprocess.check_output([prepare_script, config.apple_platform, config.clang]).decode().strip()
  except subprocess.CalledProcessError as e:
    print("Command failed:")
    print(e.output)
    raise e
  if len(prepare_output) > 0: print(prepare_output)
  prepare_output_json = prepare_output.split("\n")[-1]
  prepare_output = json.loads(prepare_output_json)
  config.environment.update(prepare_output["env"])
elif config.android:
  config.available_features.add('android')
  compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "android_commands", "android_compile.py") + " "
  config.compile_wrapper = compile_wrapper
  config.substitutions.append( ('%run', "") )
  config.substitutions.append( ('%env ', "env ") )
else:
  config.substitutions.append( ('%run', "") )
  config.substitutions.append( ('%env ', "env ") )
  # When running locally %device_rm is a no-op.
  config.substitutions.append( ('%device_rm', 'echo ') )
  config.compile_wrapper = ""

# Define CHECK-%os to check for OS-dependent output.
config.substitutions.append( ('CHECK-%os', ("CHECK-" + config.host_os)))

# Define %arch to check for architecture-dependent output.
config.substitutions.append( ('%arch', (config.host_arch)))

if config.host_os == 'Windows':
  # FIXME: This isn't quite right. Specifically, it will succeed if the program
  # does not crash but exits with a non-zero exit code. We ought to merge
  # KillTheDoctor and not --crash to make the latter more useful and remove the
  # need for this substitution.
  config.expect_crash = "not KillTheDoctor "
else:
  config.expect_crash = "not --crash "

config.substitutions.append( ("%expect_crash ", config.expect_crash) )

target_arch = getattr(config, 'target_arch', None)
if target_arch:
  config.available_features.add(target_arch + '-target-arch')
  if target_arch in ['x86_64', 'i386']:
    config.available_features.add('x86-target-arch')
  config.available_features.add(target_arch + '-' + config.host_os.lower())

compiler_rt_debug = getattr(config, 'compiler_rt_debug', False)
if not compiler_rt_debug:
  config.available_features.add('compiler-rt-optimized')

libdispatch = getattr(config, 'compiler_rt_intercept_libdispatch', False)
if libdispatch:
  config.available_features.add('libdispatch')

sanitizer_can_use_cxxabi = getattr(config, 'sanitizer_can_use_cxxabi', True)
if sanitizer_can_use_cxxabi:
  config.available_features.add('cxxabi')

if not getattr(config, 'sanitizer_uses_static_cxxabi', False):
  config.available_features.add('shared_cxxabi')

if not getattr(config, 'sanitizer_uses_static_unwind', False):
  config.available_features.add('shared_unwind')

if config.has_lld:
  config.available_features.add('lld-available')

if config.use_lld:
  config.available_features.add('lld')

if config.can_symbolize:
  config.available_features.add('can-symbolize')

if config.gwp_asan:
  config.available_features.add('gwp_asan')

lit.util.usePlatformSdkOnDarwin(config, lit_config)

min_macos_deployment_target_substitutions = [
  (10, 11),
  (10, 12),
]
# TLS requires watchOS 3+
config.substitutions.append( ('%darwin_min_target_with_tls_support', '%min_macos_deployment_target=10.12') )

if config.host_os == 'Darwin':
  osx_version = (10, 0, 0)
  try:
    osx_version = subprocess.check_output(["sw_vers", "-productVersion"],
                                          universal_newlines=True)
    osx_version = tuple(int(x) for x in osx_version.split('.'))
    if len(osx_version) == 2: osx_version = (osx_version[0], osx_version[1], 0)
    if osx_version >= (10, 11):
      config.available_features.add('osx-autointerception')
      config.available_features.add('osx-ld64-live_support')
    if osx_version >= (10, 15):
      config.available_features.add('osx-swift-runtime')
  except subprocess.CalledProcessError:
    pass

  config.darwin_osx_version = osx_version

  # Detect x86_64h
  try:
    output = subprocess.check_output(["sysctl", "hw.cpusubtype"])
    output_re = re.match("^hw.cpusubtype: ([0-9]+)$", output)
    if output_re:
      cpu_subtype = int(output_re.group(1))
      if cpu_subtype == 8: # x86_64h
        config.available_features.add('x86_64h')
  except:
    pass

  # 32-bit iOS simulator is deprecated and removed in latest Xcode.
  if config.apple_platform == "iossim":
    if config.target_arch == "i386":
      config.unsupported = True

  def get_macos_aligned_version(macos_vers):
    platform = config.apple_platform
    if platform == 'osx':
      return macos_vers

    macos_major, macos_minor = macos_vers
    assert macos_major >= 10

    if macos_major == 10:  # macOS 10.x
      major = macos_minor
      minor = 0
    else:                  # macOS 11+
      major = macos_major + 5
      minor = macos_minor

    assert major >= 11

    if platform.startswith('ios') or platform.startswith('tvos'):
      major -= 2
    elif platform.startswith('watch'):
      major -= 9
    else:
      lit_config.fatal("Unsupported apple platform '{}'".format(platform))

    return (major, minor)

  for vers in min_macos_deployment_target_substitutions:
    flag = config.apple_platform_min_deployment_target_flag
    major, minor = get_macos_aligned_version(vers)
    if 'mtargetos' in flag:
      sim = '-simulator' if 'sim' in config.apple_platform else ''
      config.substitutions.append( ('%%min_macos_deployment_target=%s.%s' % vers, '{}{}.{}{}'.format(flag, major, minor, sim)) )
    else:
      config.substitutions.append( ('%%min_macos_deployment_target=%s.%s' % vers, '{}={}.{}'.format(flag, major, minor)) )
else:
  for vers in min_macos_deployment_target_substitutions:
    config.substitutions.append( ('%%min_macos_deployment_target=%s.%s' % vers, '') )

if config.android:
  env = os.environ.copy()
  if config.android_serial:
    env['ANDROID_SERIAL'] = config.android_serial
    config.environment['ANDROID_SERIAL'] = config.android_serial

  adb = os.environ.get('ADB', 'adb')

  # These are needed for tests to upload/download temp files, such as
  # suppression-files, to device.
  config.substitutions.append( ('%device_rundir/', "/data/local/tmp/Output/") )
  config.substitutions.append( ('%push_to_device', "%s -s '%s' push " % (adb, env['ANDROID_SERIAL']) ) )
  config.substitutions.append( ('%adb_shell ', "%s -s '%s' shell " % (adb, env['ANDROID_SERIAL']) ) )
  config.substitutions.append( ('%device_rm', "%s -s '%s' shell 'rm ' " % (adb, env['ANDROID_SERIAL']) ) )

  try:
    android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip()
    android_api_codename = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.codename"], env=env).rstrip().decode("utf-8")
  except (subprocess.CalledProcessError, OSError):
    lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb)" % adb)
  try:
    android_api_level = int(android_api_level_str)
  except ValueError:
    lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb): got '%s'" % (adb, android_api_level_str))
  android_api_level = min(android_api_level, int(config.android_api_level))
  for required in [26, 28, 29, 30]:
    if android_api_level >= required:
      config.available_features.add('android-%s' % required)
  # FIXME: Replace with appropriate version when availible.
  if android_api_level > 30 or (android_api_level == 30 and android_api_codename == 'S'):
    config.available_features.add('android-thread-properties-api')

  # Prepare the device.
  android_tmpdir = '/data/local/tmp/Output'
  subprocess.check_call([adb, "shell", "mkdir", "-p", android_tmpdir], env=env)
  for file in config.android_files_to_push:
    subprocess.check_call([adb, "push", file, android_tmpdir], env=env)
else:
  config.substitutions.append( ('%device_rundir/', "") )
  config.substitutions.append( ('%push_to_device', "echo ") )
  config.substitutions.append( ('%adb_shell', "echo ") )

if config.host_os == 'Linux':
  # detect whether we are using glibc, and which version
  # NB: 'ldd' is just one of the tools commonly installed as part of glibc/musl
  ldd_ver_cmd = subprocess.Popen(['ldd', '--version'],
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.DEVNULL,
                                 env={'LANG': 'C'})
  sout, _ = ldd_ver_cmd.communicate()
  ver_lines = sout.splitlines()
  if not config.android and len(ver_lines) and ver_lines[0].startswith(b"ldd "):
    from distutils.version import LooseVersion
    ver = LooseVersion(ver_lines[0].split()[-1].decode())
    for required in ["2.27", "2.30", "2.34"]:
      if ver >= LooseVersion(required):
        config.available_features.add("glibc-" + required)

sancovcc_path = os.path.join(config.llvm_tools_dir, "sancov")
if os.path.exists(sancovcc_path):
  config.available_features.add("has_sancovcc")
  config.substitutions.append( ("%sancovcc ", sancovcc_path) )

def liblto_path():
  return os.path.join(config.llvm_shlib_dir, 'libLTO.dylib')

def is_darwin_lto_supported():
  return os.path.exists(liblto_path())

def is_binutils_lto_supported():
  if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')):
    return False

  # We require both ld.bfd and ld.gold exist and support plugins. They are in
  # the same repository 'binutils-gdb' and usually built together.
  for exe in (config.gnu_ld_executable, config.gold_executable):
    ld_cmd = subprocess.Popen([exe, '--help'], stdout=subprocess.PIPE, env={'LANG': 'C'})
    ld_out = ld_cmd.stdout.read().decode()
    ld_cmd.wait()
    if not '-plugin' in ld_out:
      return False

  return True

def is_windows_lto_supported():
  return os.path.exists(os.path.join(config.llvm_tools_dir, 'lld-link.exe'))

if config.host_os == 'Darwin' and is_darwin_lto_supported():
  config.lto_supported = True
  config.lto_flags = [ '-Wl,-lto_library,' + liblto_path() ]
elif config.host_os in ['Linux', 'FreeBSD', 'NetBSD']:
  config.lto_supported = False
  if config.use_lld:
    config.lto_supported = True
  if is_binutils_lto_supported():
    config.available_features.add('binutils_lto')
    config.lto_supported = True

  if config.lto_supported:
    if config.use_lld:
      config.lto_flags = ["-fuse-ld=lld"]
    else:
      config.lto_flags = ["-fuse-ld=gold"]
elif config.host_os == 'Windows' and is_windows_lto_supported():
  config.lto_supported = True
  config.lto_flags = ["-fuse-ld=lld"]
else:
  config.lto_supported = False

if config.lto_supported:
  config.available_features.add('lto')
  if config.use_thinlto:
    config.available_features.add('thinlto')
    config.lto_flags += ["-flto=thin"]
  else:
    config.lto_flags += ["-flto"]

if config.have_rpc_xdr_h:
  config.available_features.add('sunrpc')

# Ask llvm-config about assertion mode.
try:
  llvm_config_cmd = subprocess.Popen(
      [os.path.join(config.llvm_tools_dir, 'llvm-config'), '--assertion-mode'],
      stdout = subprocess.PIPE,
      env=config.environment)
except OSError as e:
  print("Could not launch llvm-config in " + config.llvm_tools_dir)
  print("    Failed with error #{0}: {1}".format(e.errno, e.strerror))
  exit(42)

if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
  config.available_features.add('asserts')
llvm_config_cmd.wait()

# Sanitizer tests tend to be flaky on Windows due to PR24554, so add some
# retries. We don't do this on otther platforms because it's slower.
if platform.system() == 'Windows':
  config.test_retry_attempts = 2

# No throttling on non-Darwin platforms.
lit_config.parallelism_groups['shadow-memory'] = None

if platform.system() == 'Darwin':
  ios_device = config.apple_platform != 'osx' and not config.apple_platform.endswith('sim')
  # Force sequential execution when running tests on iOS devices.
  if ios_device:
    lit_config.warning('Forcing sequential execution for iOS device tests')
    lit_config.parallelism_groups['ios-device'] = 1
    config.parallelism_group = 'ios-device'

  # Only run up to 3 processes that require shadow memory simultaneously on
  # 64-bit Darwin. Using more scales badly and hogs the system due to
  # inefficient handling of large mmap'd regions (terabytes) by the kernel.
  else:
    lit_config.warning('Throttling sanitizer tests that require shadow memory on Darwin')
    lit_config.parallelism_groups['shadow-memory'] = 3

# Multiple substitutions are necessary to support multiple shared objects used
# at once.
# Note that substitutions with numbers have to be defined first to avoid
# being subsumed by substitutions with smaller postfix.
for postfix in ["2", "1", ""]:
  if config.host_os == 'Darwin':
    config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, '-Wl,-rpath,@executable_path/ %dynamiclib' + postfix) )
    config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '-install_name @rpath/`basename %dynamiclib{}`'.format(postfix)) )
  elif config.host_os in ('FreeBSD', 'NetBSD', 'OpenBSD'):
    config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) )
    config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') )
  elif config.host_os == 'Linux':
    config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) )
    config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') )
  elif config.host_os == 'SunOS':
    config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-R\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) )
    config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') )

  # Must be defined after the substitutions that use %dynamiclib.
  config.substitutions.append( ("%dynamiclib" + postfix, '%T/%xdynamiclib_filename' + postfix) )
  config.substitutions.append( ("%xdynamiclib_filename" + postfix, 'lib%xdynamiclib_namespec{}.so'.format(postfix)) )
  config.substitutions.append( ("%xdynamiclib_namespec", '%basename_t.dynamic') )

# Provide a substitution that can be used to tell Clang to use a static libstdc++.
# The substitution expands to nothing on non Linux platforms.
# FIXME: This should check the target OS, not the host OS.
if config.host_os == 'Linux':
  config.substitutions.append( ("%linux_static_libstdcplusplus", "-stdlib=libstdc++ -static-libstdc++") )
else:
  config.substitutions.append( ("%linux_static_libstdcplusplus", "") )

config.default_sanitizer_opts = []
if config.host_os == 'Darwin':
  # On Darwin, we default to `abort_on_error=1`, which would make tests run
  # much slower. Let's override this and run lit tests with 'abort_on_error=0'.
  config.default_sanitizer_opts += ['abort_on_error=0']
  config.default_sanitizer_opts += ['log_to_syslog=0']
  if lit.util.which('log'):
    # Querying the log can only done by a privileged user so
    # so check if we can query the log.
    exit_code = -1
    with open('/dev/null', 'r') as f:
      # Run a `log show` command the should finish fairly quickly and produce very little output.
      exit_code = subprocess.call(['log', 'show', '--last', '1m', '--predicate', '1 == 0'], stdout=f, stderr=f)
    if exit_code == 0:
      config.available_features.add('darwin_log_cmd')
    else:
      lit_config.warning('log command found but cannot queried')
  else:
    lit_config.warning('log command not found. Some tests will be skipped.')
elif config.android:
  config.default_sanitizer_opts += ['abort_on_error=0']

# Allow tests to use REQUIRES=stable-runtime.  For use when you cannot use XFAIL
# because the test hangs or fails on one configuration and not the other.
if config.android or (config.target_arch not in ['arm', 'armhf', 'aarch64']):
  config.available_features.add('stable-runtime')

if config.asan_shadow_scale:
  config.available_features.add("shadow-scale-%s" % config.asan_shadow_scale)
else:
  config.available_features.add("shadow-scale-3")

if config.memprof_shadow_scale:
  config.available_features.add("memprof-shadow-scale-%s" % config.memprof_shadow_scale)
else:
  config.available_features.add("memprof-shadow-scale-3")

if config.expensive_checks:
  config.available_features.add("expensive_checks")

# Propagate the LLD/LTO into the clang config option, so nothing else is needed.
run_wrapper = []
target_cflags = [getattr(config, 'target_cflags', None)]
extra_cflags = []

if config.use_lto and config.lto_supported:
  extra_cflags += config.lto_flags
elif config.use_lto and (not config.lto_supported):
  config.unsupported = True

if config.use_lld and config.has_lld and not config.use_lto:
  extra_cflags += ["-fuse-ld=lld"]
elif config.use_lld and (not config.has_lld):
  config.unsupported = True

# Append any extra flags passed in lit_config
append_target_cflags = lit_config.params.get('append_target_cflags', None)
if append_target_cflags:
  lit_config.note('Appending to extra_cflags: "{}"'.format(append_target_cflags))
  extra_cflags += [append_target_cflags]

config.clang = " " + " ".join(run_wrapper + [config.compile_wrapper, config.clang]) + " "
config.target_cflags = " " + " ".join(target_cflags + extra_cflags) + " "

if config.host_os == 'Darwin':
  config.substitutions.append((
    "%get_pid_from_output",
    "{} {}/get_pid_from_output.py".format(
      sh_quote(config.python_executable),
      sh_quote(get_ios_commands_dir())
    ))
  )
  config.substitutions.append(
    ("%print_crashreport_for_pid",
    "{} {}/print_crashreport_for_pid.py".format(
      sh_quote(config.python_executable),
      sh_quote(get_ios_commands_dir())
    ))
  )
