# -*- Python -*-

import os
import platform

import lit.formats

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_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

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

# Setup default ASAN_OPTIONS
config.environment['ASAN_OPTIONS'] = 'symbolize_vs_style=false'

# testFormat: The test format to use to interpret tests.
external_bash = (not sys.platform in ['win32'])
config.test_format = lit.formats.ShTest(external_bash)

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

# There is no libdl on FreeBSD.
if config.host_os != 'FreeBSD':
  libdl_flag = "-ldl"
else:
  libdl_flag = ""

# 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++", libdl_flag]
else:
  extra_linkflags = []

# 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:
  config.available_features.add('not-android')
  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.substitutions.append( ("%libdl", libdl_flag) )

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

if config.host_os == 'Darwin':
  config.substitutions.append( ("%ld_flags_rpath_exe", '-Wl,-rpath,@executable_path/ %dynamiclib') )
  config.substitutions.append( ("%ld_flags_rpath_so", '-install_name @rpath/`basename %dynamiclib`') )
elif config.host_os == 'FreeBSD':
  config.substitutions.append( ("%ld_flags_rpath_exe", "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec") )
  config.substitutions.append( ("%ld_flags_rpath_so", '') )
elif config.host_os == 'Linux':
  config.substitutions.append( ("%ld_flags_rpath_exe", "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec") )
  config.substitutions.append( ("%ld_flags_rpath_so", '') )

# Must be defined after the substitutions that use %dynamiclib.
config.substitutions.append( ("%dynamiclib", '%T/lib%xdynamiclib_namespec.so') )
config.substitutions.append( ("%xdynamiclib_namespec", '$(basename %t).dynamic') )

# 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.target_arch == 'x86_64':
  config.available_features.add('leak-detection')

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

# 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
