# -*- 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


def push_dynamic_library_lookup_path(config, new_path):
    if platform.system() == "Windows":
        dynamic_library_lookup_var = "PATH"
    elif platform.system() == "Darwin":
        dynamic_library_lookup_var = "DYLD_LIBRARY_PATH"
    else:
        dynamic_library_lookup_var = "LD_LIBRARY_PATH"

    new_ld_library_path = os.path.pathsep.join(
        (new_path, config.environment.get(dynamic_library_lookup_var, ""))
    )
    config.environment[dynamic_library_lookup_var] = new_ld_library_path

    if platform.system() == "FreeBSD":
        dynamic_library_lookup_var = "LD_32_LIBRARY_PATH"
        new_ld_32_library_path = os.path.pathsep.join(
            (new_path, config.environment.get(dynamic_library_lookup_var, ""))
        )
        config.environment[dynamic_library_lookup_var] = new_ld_32_library_path

    if platform.system() == "SunOS":
        dynamic_library_lookup_var = "LD_LIBRARY_PATH_32"
        new_ld_library_path_32 = os.path.pathsep.join(
            (new_path, config.environment.get(dynamic_library_lookup_var, ""))
        )
        config.environment[dynamic_library_lookup_var] = new_ld_library_path_32

        dynamic_library_lookup_var = "LD_LIBRARY_PATH_64"
        new_ld_library_path_64 = os.path.pathsep.join(
            (new_path, config.environment.get(dynamic_library_lookup_var, ""))
        )
        config.environment[dynamic_library_lookup_var] = new_ld_library_path_64


# 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":
    def add_glibc_versions(ver_string):
        if config.android:
            return

        from distutils.version import LooseVersion

        ver = LooseVersion(ver_string)
        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")

    # detect whether we are using glibc, and which version
    cmd_args = [
        config.clang.strip(),
        f"--target={config.target_triple}",
        "-xc",
        "-",
        "-o",
        "-",
        "-dM",
        "-E",
    ] + shlex.split(config.target_cflags)
    cmd = subprocess.Popen(
        cmd_args,
        stdout=subprocess.PIPE,
        stdin=subprocess.PIPE,
        stderr=subprocess.DEVNULL,
        env={"LANG": "C"},
    )
    try:
        sout, _ = cmd.communicate(b"#include <features.h>")
        m = dict(re.findall(r"#define (__GLIBC__|__GLIBC_MINOR__) (\d+)", str(sout)))
        add_glibc_versions(f"{m['__GLIBC__']}.{m['__GLIBC_MINOR__']}")
    except:
        pass

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"

# Set LD_LIBRARY_PATH to pick dynamic runtime up properly.
push_dynamic_library_lookup_path(config, config.compiler_rt_libdir)

# GCC-ASan uses dynamic runtime by default.
if config.compiler_id == "GNU":
    gcc_dir = os.path.dirname(config.clang)
    libasan_dir = os.path.join(gcc_dir, "..", "lib" + config.bits)
    push_dynamic_library_lookup_path(config, libasan_dir)
