# -*- Python -*-

import os

import lit.util

def get_required_attr(config, attr_name):
  attr_value = getattr(config, attr_name, None)
  if not attr_value:
    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

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

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

def DisplayNoConfigMessage():
  lit_config.fatal("No site specific configuration available! " +
                   "Try running your test from the build tree or running " +
                   "make check-asan")

# Figure out LLVM source root.
llvm_src_root = getattr(config, 'llvm_src_root', None)
if llvm_src_root is None:
  # We probably haven't loaded the site-specific configuration: the user
  # is likely trying to run a test file directly, and the site configuration
  # wasn't created by the build system.
  asan_site_cfg = lit_config.params.get('asan_site_config', None)
  if (asan_site_cfg) and (os.path.exists(asan_site_cfg)):
    lit_config.load_config(config, asan_site_cfg)
    raise SystemExit

  # Try to guess the location of site-specific configuration using llvm-config
  # util that can point where the build tree is.
  llvm_config = lit.util.which("llvm-config", config.environment["PATH"])
  if not llvm_config:
    DisplayNoConfigMessage()

  # Find out the presumed location of generated site config.
  llvm_obj_root = lit.util.capture(["llvm-config", "--obj-root"]).strip()
  asan_site_cfg = os.path.join(llvm_obj_root, "projects", "compiler-rt",
                               "lib", "asan", "lit_tests", "lit.site.cfg")
  if (not asan_site_cfg) or (not os.path.exists(asan_site_cfg)):
    DisplayNoConfigMessage()

  lit_config.load_config(config, asan_site_cfg)
  raise SystemExit

# Setup default compiler flags used with -fsanitize=address option.
# FIXME: Review the set of required flags and check if it can be reduced.
bits_cflag = " -m" + config.bits
clang_asan_cflags = (" -fsanitize=address"
                   + " -mno-omit-leaf-frame-pointer"
                   + " -fno-omit-frame-pointer"
                   + " -fno-optimize-sibling-calls"
                   + " -g"
                   + bits_cflag)
clang_asan_cxxflags = " --driver-mode=g++" + clang_asan_cflags
config.substitutions.append( ("%clang ", " " + config.clang + bits_cflag + " "))
config.substitutions.append( ("%clangxx ", (" " + config.clang +
                                            " --driver-mode=g++" +
                                            bits_cflag + " ")) )
config.substitutions.append( ("%clang_asan ", (" " + config.clang + " " +
                                              clang_asan_cflags + " ")) )
config.substitutions.append( ("%clangxx_asan ", (" " + config.clang + " " +
                                                clang_asan_cxxflags + " ")) )

# Setup path to asan_symbolize.py script.
asan_source_dir = get_required_attr(config, "asan_source_dir")
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 + " ") )

# Define CHECK-%os to check for OS-dependent output.
config.substitutions.append( ('CHECK-%os', ("CHECK-" + config.host_os)))

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

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

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

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