# -*- Python -*-

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

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

# Setup clang binary.
compiler_path = getattr(config, 'clang', None)
if (not compiler_path) or (not os.path.exists(compiler_path)):
  lit_config.fatal("Can't find compiler on path %r" % compiler_path)

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':
    config.debug_info_flags.append("-gcodeview")
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)

# 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.
llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
if (not llvm_tools_dir) or (not os.path.exists(llvm_tools_dir)):
  lit_config.fatal("Invalid llvm_tools_dir config attribute: %r" % llvm_tools_dir)
path = os.path.pathsep.join((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']

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

if lit.util.isMacOSTriple(config.target_triple):
   config.available_features.add('darwin')

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

# Allow tests to be executed on a simulator or remotely.
if config.emulator:
  config.substitutions.append( ('%run', config.emulator) )
  config.substitutions.append( ('%env ', "env ") )
  config.compile_wrapper = ""
elif config.ios:
  config.available_features.add('ios')

  device_id_env = "SANITIZER_IOSSIM_TEST_DEVICE_IDENTIFIER" if config.iossim else "SANITIZER_IOS_TEST_DEVICE_IDENTIFIER"
  if device_id_env in os.environ: config.environment[device_id_env] = os.environ[device_id_env]
  ios_commands_dir = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ios_commands")
  run_wrapper = os.path.join(ios_commands_dir, "iossim_run.py" if config.iossim else "ios_run.py")
  config.substitutions.append(('%run', run_wrapper))
  env_wrapper = os.path.join(ios_commands_dir, "iossim_env.py" if config.iossim else "ios_env.py")
  config.substitutions.append(('%env ', env_wrapper + " "))
  compile_wrapper = os.path.join(ios_commands_dir, "iossim_compile.py" if config.iossim else "ios_compile.py")
  config.compile_wrapper = compile_wrapper
else:
  config.substitutions.append( ('%run', "") )
  config.substitutions.append( ('%env ', "env ") )
  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', 'i686']:
    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')

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

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.cc 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") )
else:
  config.substitutions.append( ("%macos_min_target_10_11", "") )

sancovcc_path = os.path.join(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 == 'Linux' 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 = []
  # FIXME: Remove -nopdb when PDB writing is ready.
  config.lto_flags = ["-fuse-ld=lld -Wl,-nopdb"]
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"]

# 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:
  print("Could not find llvm-config in " + llvm_tools_dir)
  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

# Only run up to 3 64-bit sanitized processes simultaneously on Darwin.
# Using more scales badly and hogs the system due to inefficient handling
# of large mmap'd regions (terabytes) by the kernel.
if platform.system() == 'Darwin':
  lit_config.parallelism_groups["darwin-64bit-sanitizer"] = 3
