# -*- Python -*-

import os

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

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

def DisplayNoConfigMessage():
  lit.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.params.get('asan_site_config', None)
  if (asan_site_cfg) and (os.path.exists(asan_site_cfg)):
    lit.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.load_config(config, asan_site_cfg)
  raise SystemExit

# Setup attributes common for all compiler-rt projects.
compiler_rt_src_root = get_required_attr(config, "compiler_rt_src_root")
compiler_rt_lit_cfg = os.path.join(compiler_rt_src_root, "lib",
                                   "lit.common.cfg")
if (not compiler_rt_lit_cfg) or (not os.path.exists(compiler_rt_lit_cfg)):
  lit.fatal("Can't find common compiler-rt lit config at: %r"
            % compiler_rt_lit_cfg)
lit.load_config(config, compiler_rt_lit_cfg)

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

# Setup path to external LLVM symbolizer to run AddressSanitizer output tests.
llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
if llvm_tools_dir:
  config.environment['LLVM_SYMBOLIZER_PATH'] = os.path.join(
      llvm_tools_dir, "llvm-symbolizer")

# Setup path to symbolizer script.
# FIXME: Instead we should copy this script to the build tree and point
#        at it there.
asan_source_dir = os.path.join(config.test_source_root, "..")
symbolizer = os.path.join(asan_source_dir,
                         'scripts', 'asan_symbolize.py')
if not os.path.exists(symbolizer):
  lit.fatal("Can't find symbolizer script on path %r" % symbolizer)
# Define %symbolize substitution that filters output through
# symbolizer and c++filt (for demangling).
config.substitutions.append( ("%symbolize ", (" " + symbolizer +
                                              " | c++filt " )))

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

# 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
