# -*- Python -*-

import os
import platform

def get_required_attr(config, attr_name):
  attr_value = getattr(config, attr_name, None)
  if attr_value == None:
    lit_config.fatal(
      "No attribute %r in test configuration! You may need to run "
      "tests from your build directory or add this attribute "
      "to lit.site.cfg " % attr_name)
  return attr_value

def push_ld_library_path(config, new_path):
  new_ld_library_path = os.path.pathsep.join(
    (new_path, config.environment['LD_LIBRARY_PATH']))
  config.environment['LD_LIBRARY_PATH'] = new_ld_library_path

# Setup config name.
config.name = 'AddressSanitizer' + config.name_suffix

# Setup source root.
config.test_source_root = os.path.dirname(__file__)

# GCC-ASan doesn't link in all the necessary libraries automatically, so
# we have to do it ourselves.
if config.compiler_id == 'GNU':
  extra_linkflags = ["-pthread", "-lstdc++"]
else:
  extra_linkflags = []

# There is no libdl on FreeBSD.
if config.compiler_id == 'GNU' and config.host_os != 'FreeBSD':
  extra_linkflags += ["-ldl"]

# Setup default compiler flags used with -fsanitize=address option.
# FIXME: Review the set of required flags and check if it can be reduced.
target_cflags = [get_required_attr(config, "target_cflags")] + extra_linkflags
target_cxxflags = config.cxx_mode_flags + target_cflags
clang_asan_static_cflags = (["-fsanitize=address",
                            "-mno-omit-leaf-frame-pointer",
                            "-fno-omit-frame-pointer",
                            "-fno-optimize-sibling-calls"] +
                            config.debug_info_flags + target_cflags)
clang_asan_static_cxxflags = config.cxx_mode_flags + clang_asan_static_cflags

if config.asan_dynamic:
  clang_asan_cflags = clang_asan_static_cflags + ['-shared-libasan']
  clang_asan_cxxflags = clang_asan_static_cxxflags + ['-shared-libasan']
  config.available_features.add("asan-dynamic-runtime")
else:
  clang_asan_cflags = clang_asan_static_cflags
  clang_asan_cxxflags = clang_asan_static_cxxflags
  config.available_features.add("asan-static-runtime")

asan_lit_source_dir = get_required_attr(config, "asan_lit_source_dir")
if config.android == "1":
  config.available_features.add('android')
  clang_wrapper = os.path.join(asan_lit_source_dir,
                               "android_commands", "android_compile.py") + " "
else:
  clang_wrapper = ""

def build_invocation(compile_flags):
  return " " + " ".join([clang_wrapper, config.clang] + compile_flags) + " "

config.substitutions.append( ("%clang ", build_invocation(target_cflags)) )
config.substitutions.append( ("%clangxx ", build_invocation(target_cxxflags)) )
config.substitutions.append( ("%clang_asan ", build_invocation(clang_asan_cflags)) )
config.substitutions.append( ("%clangxx_asan ", build_invocation(clang_asan_cxxflags)) )
config.substitutions.append( ("%shared_libasan", "libclang_rt.asan-%s.so" % config.target_arch))
if config.asan_dynamic:
  config.substitutions.append( ("%clang_asan_static ", build_invocation(clang_asan_static_cflags)) )
  config.substitutions.append( ("%clangxx_asan_static ", build_invocation(clang_asan_static_cxxflags)) )

# Windows-specific tests might also use the clang-cl.exe driver.
if platform.system() == 'Windows':
  clang_cl_asan_cxxflags = ["-fsanitize=address",
                            "-Wno-deprecated-declarations",
                            "-WX",
                            "-D_HAS_EXCEPTIONS=0",
                            "-Zi"] + target_cflags
  if config.asan_dynamic:
    clang_cl_asan_cxxflags.append("-MD")
  clang_invocation = build_invocation(clang_cl_asan_cxxflags)
  clang_cl_invocation = clang_invocation.replace("clang.exe","clang-cl.exe")
  config.substitutions.append( ("%clang_cl_asan ", clang_cl_invocation) )
  config.substitutions.append( ("%asan_dll_thunk",
                               os.path.join(config.compiler_rt_libdir, "clang_rt.asan_dll_thunk-i386.lib")))

# FIXME: De-hardcode this path.
asan_source_dir = os.path.join(
  get_required_attr(config, "compiler_rt_src_root"), "lib", "asan")
# Setup path to asan_symbolize.py script.
asan_symbolize = os.path.join(asan_source_dir, "scripts", "asan_symbolize.py")
if not os.path.exists(asan_symbolize):
  lit_config.fatal("Can't find script on path %r" % asan_symbolize)
python_exec = get_required_attr(config, "python_executable")
config.substitutions.append( ("%asan_symbolize", python_exec + " " + asan_symbolize + " ") )
# Setup path to sancov.py script.
sanitizer_common_source_dir = os.path.join(
  get_required_attr(config, "compiler_rt_src_root"), "lib", "sanitizer_common")
sancov = os.path.join(sanitizer_common_source_dir, "scripts", "sancov.py")
if not os.path.exists(sancov):
  lit_config.fatal("Can't find script on path %r" % sancov)
python_exec = get_required_attr(config, "python_executable")
config.substitutions.append( ("%sancov", python_exec + " " + sancov + " ") )

# Determine kernel bitness
if config.host_arch.find('64') != -1 and config.android != "1":
  kernel_bits = '64'
else:
  kernel_bits = '32'

config.substitutions.append( ('CHECK-%kernel_bits', ("CHECK-kernel-" + kernel_bits + "-bits")))

config.available_features.add("asan-" + config.bits + "-bits")

# Allow tests to use REQUIRES=stable-runtime.  For use when you cannot use XFAIL
# because the test hangs.
if config.target_arch != 'arm':
  config.available_features.add('stable-runtime')

# Turn on leak detection on 64-bit Linux.
if config.host_os == 'Linux' and config.bits == '64':
  config.environment['ASAN_OPTIONS'] = 'detect_leaks=1'

# Set LD_LIBRARY_PATH to pick dynamic runtime up properly.
push_ld_library_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_ld_library_path(config, libasan_dir)

# Default test suffixes.
config.suffixes = ['.c', '.cc', '.cpp']

if config.host_os == 'Darwin':
  config.suffixes.append('.mm')

# AddressSanitizer tests are currently supported on Linux, Darwin and
# FreeBSD only.
if config.host_os not in ['Linux', 'Darwin', 'FreeBSD']:
  config.unsupported = True
