# -*- 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 = 'ThreadSanitizer'

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

# 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.
  tsan_site_cfg = lit.params.get('tsan_site_config', None)
  if (tsan_site_cfg) and (os.path.exists(tsan_site_cfg)):
    lit.load_config(config, tsan_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()
  tsan_site_cfg = os.path.join(llvm_obj_root, "projects", "compiler-rt",
                               "lib", "tsan", "lit_tests", "lit.site.cfg")
  if (not tsan_site_cfg) or (not os.path.exists(tsan_site_cfg)):
    DisplayNoConfigMessage()

  lit.load_config(config, tsan_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 environment variables for running ThreadSanitizer.
tsan_options = "atexit_sleep_ms=0"
# Get path to external LLVM symbolizer to run ThreadSanitizer output tests.
llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
if llvm_tools_dir:
  llvm_symbolizer_path = os.path.join(llvm_tools_dir, "llvm-symbolizer")
  tsan_options += " " + "external_symbolizer_path=" + llvm_symbolizer_path

config.environment['TSAN_OPTIONS'] = tsan_options

# Setup default compiler flags used with -fsanitize=thread option.
# FIXME: Review the set of required flags and check if it can be reduced.
clang_tsan_cflags = ("-fsanitize=thread "
                      + "-g "
                      + "-Wall "
                      + "-lpthread "
                      + "-ldl ")
clang_tsan_cxxflags = "-ccc-cxx " + clang_tsan_cflags
config.substitutions.append( ("%clangxx_tsan ", (" " + config.clang + " " +
                                                clang_tsan_cxxflags + " ")) )
config.substitutions.append( ("%clang_tsan ", (" " + config.clang + " " +
                                              clang_tsan_cflags + " ")) )

# 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']

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