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

# 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'])

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

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

# BFD linker in 64-bit android toolchains fails to find libc++_shared.so, which
# is a transitive shared library dependency (via asan runtime).
if config.android:
  # Prepend the flag so that it can be overridden.
  config.target_cflags = "-pie -fuse-ld=gold " + config.target_cflags
  if config.android_ndk_version < 19:
    # With a new compiler and NDK < r19 this flag ends up meaning "link against
    # libc++", but NDK r19 makes this mean "link against the stub libstdc++ that
    # just contains a handful of ABI functions", which makes most C++ code fail
    # to link. In r19 and later we just use the default which is libc++.
    config.cxx_mode_flags.append('-stdlib=libstdc++')

# 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 re.match(r'^x86_64.*-linux', config.target_triple):
  config.available_features.add("x86_64-linux")

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

# Allow tests to be executed on a simulator or remotely.
if config.emulator:
  config.substitutions.append( ('%run', config.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 = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ios_commands")

  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]).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 ") )
  # TODO: Implement `%device_rm` to perform removal of files on a device.  For
  # now just make it a no-op.
  lit_config.warning('%device_rm is not implemented')
  config.substitutions.append( ('%device_rm', 'echo ') )
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 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)

if config.host_os == 'Darwin':
  osx_version = (10, 0, 0)
  try:
    osx_version = subprocess.check_output(["sw_vers", "-productVersion"])
    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')
    else:
      # The ASAN initialization-bug.cpp test should XFAIL on OS X systems
      # older than El Capitan. By marking the test as being unsupported with
      # this "feature", we can pass the test on newer OS X versions and other
      # platforms.
      config.available_features.add('osx-no-ld64-live_support')
  except:
    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

  config.substitutions.append( ("%macos_min_target_10_11", "-mmacosx-version-min=10.11") )

  isIOS = config.apple_platform != "osx"
  # rdar://problem/22207160
  config.substitutions.append( ("%darwin_min_target_with_full_runtime_arc_support",
      "-miphoneos-version-min=9.0" if isIOS else "-mmacosx-version-min=10.11") )

  # 32-bit iOS simulator is deprecated and removed in latest Xcode.
  if config.apple_platform == "iossim":
    if config.target_arch == "i386":
      config.unsupported = True
else:
  config.substitutions.append( ("%macos_min_target_10_11", "") )
  config.substitutions.append( ("%darwin_min_target_with_full_runtime_arc_support", "") )

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')
  try:
    android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip()
  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))
  if android_api_level >= 26:
    config.available_features.add('android-26')
  if android_api_level >= 28:
    config.available_features.add('android-28')

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

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
  ldd_ver_cmd = subprocess.Popen(['ldd', '--version'],
                                 stdout=subprocess.PIPE,
                                 env={'LANG': 'C'})
  sout, _ = ldd_ver_cmd.communicate()
  ver_line = sout.splitlines()[0]
  if ver_line.startswith(b"ldd "):
    from distutils.version import LooseVersion
    ver = LooseVersion(ver_line.split()[-1].decode())
    # 2.27 introduced some incompatibilities
    if ver >= LooseVersion("2.27"):
      config.available_features.add("glibc-2.27")

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 is_darwin_lto_supported():
  return os.path.exists(os.path.join(config.llvm_shlib_dir, 'libLTO.dylib'))

def is_linux_lto_supported():
  if config.use_lld:
    return True

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

  ld_cmd = subprocess.Popen([config.gold_executable, '--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_launch = ["env", "DYLD_LIBRARY_PATH=" + config.llvm_shlib_dir]
  config.lto_flags = []
elif config.host_os in ['Linux', 'FreeBSD', 'NetBSD'] and is_linux_lto_supported():
  config.lto_supported = True
  config.lto_launch = []
  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_launch = []
  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.use_newpm:
    config.lto_flags += ["-fexperimental-new-pass-manager"]

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.
  elif config.target_arch in ['x86_64', 'x86_64h']:
    lit_config.warning('Throttling sanitizer tests that require shadow memory on Darwin 64bit')
    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 substituion 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']
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.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:
  run_wrapper += config.lto_launch
  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

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