# -*- 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 shlex
import subprocess
import json

import lit.formats
import lit.util


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")

target_is_msvc = bool(re.match(r".*-windows-msvc$", config.target_triple))

compiler_id = getattr(config, "compiler_id", None)
if compiler_id == "Clang":
    if not (platform.system() == "Windows" and target_is_msvc):
        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" and target_is_msvc:
        # On MSVC, 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
    )

# Clear some environment variables that might affect Clang.
possibly_dangerous_env_vars = [
    "ASAN_OPTIONS",
    "DFSAN_OPTIONS",
    "HWASAN_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/MSVC may refer to %INCLUDE%. vsvarsall.bat sets it.
if not (platform.system() == "Windows" and target_is_msvc):
    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 target_is_msvc:
    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:
    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 >= (13, 1):
            config.available_features.add("jit-compatible-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())
        any_glibc = False
        for required in ["2.19", "2.27", "2.30", "2.34", "2.37"]:
            if ver >= LooseVersion(required):
                config.available_features.add("glibc-" + required)
                any_glibc = True
            if any_glibc:
                config.available_features.add("glibc")

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):
        try:
            ld_cmd = subprocess.Popen(
                [exe, "--help"], stdout=subprocess.PIPE, env={"LANG": "C"}
            )
            ld_out = ld_cmd.stdout.read().decode()
            ld_cmd.wait()
        except OSError:
            return False
        if not "-plugin" in ld_out:
            return False

    return True


def is_windows_lto_supported():
    if not target_is_msvc:
        return True
    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"))

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(
                shlex.quote(config.python_executable),
                shlex.quote(get_ios_commands_dir()),
            ),
        )
    )
    config.substitutions.append(
        (
            "%print_crashreport_for_pid",
            "{} {}/print_crashreport_for_pid.py".format(
                shlex.quote(config.python_executable),
                shlex.quote(get_ios_commands_dir()),
            ),
        )
    )

# It is not realistically possible to account for all options that could
# possibly be present in system and user configuration files, so disable
# default configs for the test runs. In particular, anything hardening
# related is likely to cause issues with sanitizer tests, because it may
# preempt something we're looking to trap (e.g. _FORTIFY_SOURCE vs our ASAN).
config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1"
