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