# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import sys
import re
import platform
import subprocess

import lit.util
import lit.formats

# name: The name of this test suite.
config.name = 'LLVM'

# Tweak PATH for Win32 to decide to use bash.exe or not.
if sys.platform in ['win32']:
    # Seek sane tools in directories and set to $PATH.
    path = getattr(config, 'lit_tools_dir', None)
    path = lit_config.getToolsPath(path,
                                   config.environment['PATH'],
                                   ['cmp.exe', 'grep.exe', 'sed.exe'])
    if path is not None:
        path = os.path.pathsep.join((path,
                                     config.environment['PATH']))
        config.environment['PATH'] = path

# Choose between lit's internal shell pipeline runner and a real shell.  If
# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
if use_lit_shell:
    # 0 is external, "" is default, and everything else is internal.
    execute_external = (use_lit_shell == "0")
else:
    # Otherwise we default to internal on Windows and external elsewhere, as
    # bash on Windows is usually very slow.
    execute_external = (not sys.platform in ['win32'])

# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.ShTest(execute_external)

# suffixes: A list of file extensions to treat as test files. This is overriden
# by individual lit.local.cfg files in the test subdirectories.
config.suffixes = ['.ll', '.c', '.cxx', '.test', '.txt', '.s', '.mir']

# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)

# test_exec_root: The root path where tests should be run.
llvm_obj_root = getattr(config, 'llvm_obj_root', None)
if llvm_obj_root is not None:
    config.test_exec_root = os.path.join(llvm_obj_root, 'test')

# Tweak the PATH to include the tools dir.
if llvm_obj_root is not None:
    llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
    if not llvm_tools_dir:
        lit_config.fatal('No LLVM tools dir set!')
    path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
    config.environment['PATH'] = path

# Propagate 'HOME' through the environment.
if 'HOME' in os.environ:
    config.environment['HOME'] = os.environ['HOME']

# Propagate 'INCLUDE' through the environment.
if 'INCLUDE' in os.environ:
    config.environment['INCLUDE'] = os.environ['INCLUDE']

# Propagate 'LIB' through the environment.
if 'LIB' in os.environ:
    config.environment['LIB'] = os.environ['LIB']

# Propagate the temp directory. Windows requires this because it uses \Windows\
# if none of these are present.
if 'TMP' in os.environ:
    config.environment['TMP'] = os.environ['TMP']
if 'TEMP' in os.environ:
    config.environment['TEMP'] = os.environ['TEMP']

# Propagate LLVM_SRC_ROOT into the environment.
config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '')

# Propagate PYTHON_EXECUTABLE into the environment
config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable',
                                                  '')

# Propagate path to symbolizer for ASan/MSan.
for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
    if symbolizer in os.environ:
        config.environment[symbolizer] = os.environ[symbolizer]

# Set up OCAMLPATH to include newly built OCaml libraries.
llvm_lib_dir = getattr(config, 'llvm_lib_dir', None)
if llvm_lib_dir is None:
    if llvm_obj_root is not None:
        llvm_lib_dir = os.path.join(llvm_obj_root, 'lib')

if llvm_lib_dir is not None:
    top_ocaml_lib = os.path.join(llvm_lib_dir, 'ocaml')
    llvm_ocaml_lib = os.path.join(top_ocaml_lib, 'llvm')
    if llvm_ocaml_lib is not None:
        ocamlpath = os.path.pathsep.join((llvm_ocaml_lib, top_ocaml_lib))
        if 'OCAMLPATH' in os.environ:
            ocamlpath = os.path.pathsep.join((ocamlpath, os.environ['OCAMLPATH']))
        config.environment['OCAMLPATH'] = ocamlpath

        if 'CAML_LD_LIBRARY_PATH' in os.environ:
            caml_ld_library_path = os.path.pathsep.join((llvm_ocaml_lib,
                                        os.environ['CAML_LD_LIBRARY_PATH']))
            config.environment['CAML_LD_LIBRARY_PATH'] = caml_ld_library_path
        else:
            config.environment['CAML_LD_LIBRARY_PATH'] = llvm_ocaml_lib

# Set up OCAMLRUNPARAM to enable backtraces in OCaml tests.
config.environment['OCAMLRUNPARAM'] = 'b'

###

import os

# Check that the object root is known.
if config.test_exec_root is None:
    # Otherwise, we haven't loaded the site specific configuration (the user is
    # probably trying to run on a test file directly, and either the site
    # configuration hasn't been created by the build system, or we are in an
    # out-of-tree build situation).

    # Check for 'llvm_site_config' user parameter, and use that if available.
    site_cfg = lit_config.params.get('llvm_site_config', None)
    if site_cfg and os.path.exists(site_cfg):
        lit_config.load_config(config, site_cfg)
        raise SystemExit

    # Try to detect the situation where we are using an out-of-tree build by
    # looking for 'llvm-config'.
    #
    # FIXME: I debated (i.e., wrote and threw away) adding logic to
    # automagically generate the lit.site.cfg if we are in some kind of fresh
    # build situation. This means knowing how to invoke the build system
    # though, and I decided it was too much magic.

    llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
    if not llvm_config:
        lit_config.fatal('No site specific configuration available!')

    # Get the source and object roots.
    llvm_src_root = subprocess.check_output(['llvm-config', '--src-root']).strip()
    llvm_obj_root = subprocess.check_output(['llvm-config', '--obj-root']).strip()

    # Validate that we got a tree which points to here.
    this_src_root = os.path.dirname(config.test_source_root)
    if os.path.realpath(llvm_src_root) != os.path.realpath(this_src_root):
        lit_config.fatal('No site specific configuration available!')

    # Check that the site specific configuration exists.
    site_cfg = os.path.join(llvm_obj_root, 'test', 'lit.site.cfg')
    if not os.path.exists(site_cfg):
        lit_config.fatal('No site specific configuration available!')

    # Okay, that worked. Notify the user of the automagic, and reconfigure.
    lit_config.note('using out-of-tree build at %r' % llvm_obj_root)
    lit_config.load_config(config, site_cfg)
    raise SystemExit

###

# Provide the path to asan runtime lib 'libclang_rt.asan_osx_dynamic.dylib' if
# available. This is darwin specific since it's currently only needed on darwin.
def get_asan_rtlib():
    if not "Address" in config.llvm_use_sanitizer or \
       not "Darwin" in config.host_os or \
       not "x86" in config.host_triple:
        return ""
    try:
        import glob
    except:
        print("glob module not found, skipping get_asan_rtlib() lookup")
        return ""
    # The libclang_rt.asan_osx_dynamic.dylib path is obtained using the relative
    # path from the host cc.
    host_lib_dir = os.path.join(os.path.dirname(config.host_cc), "../lib")
    asan_dylib_dir_pattern = host_lib_dir + \
        "/clang/*/lib/darwin/libclang_rt.asan_osx_dynamic.dylib"
    found_dylibs = glob.glob(asan_dylib_dir_pattern)
    if len(found_dylibs) != 1:
        return ""
    return found_dylibs[0]

lli = 'lli'
# The target triple used by default by lli is the process target triple (some
# triple appropriate for generating code for the current process) but because
# we don't support COFF in MCJIT well enough for the tests, force ELF format on
# Windows.  FIXME: the process target triple should be used here, but this is
# difficult to obtain on Windows.
if re.search(r'cygwin|mingw32|windows-gnu|windows-msvc|win32', config.host_triple):
  lli += ' -mtriple='+config.host_triple+'-elf'
config.substitutions.append( ('%lli', lli ) )

# Similarly, have a macro to use llc with DWARF even when the host is win32.
llc_dwarf = 'llc'
if re.search(r'win32', config.target_triple):
  llc_dwarf += ' -mtriple='+config.target_triple.replace('-win32', '-mingw32')
config.substitutions.append( ('%llc_dwarf', llc_dwarf) )

# Add site-specific substitutions.
config.substitutions.append( ('%gold', config.gold_executable) )
config.substitutions.append( ('%go', config.go_executable) )
config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) )
config.substitutions.append( ('%shlibext', config.llvm_shlib_ext) )
config.substitutions.append( ('%exeext', config.llvm_exe_ext) )
config.substitutions.append( ('%python', config.python_executable) )
config.substitutions.append( ('%host_cc', config.host_cc) )

# Provide the path to asan runtime lib if available. On darwin, this lib needs
# to be loaded via DYLD_INSERT_LIBRARIES before libLTO.dylib in case the files
# to be linked contain instrumented sanitizer code.
ld64_cmd = config.ld64_executable
asan_rtlib = get_asan_rtlib()
if asan_rtlib:
  ld64_cmd = "DYLD_INSERT_LIBRARIES={} {}".format(asan_rtlib, ld64_cmd)
config.substitutions.append( ('%ld64', ld64_cmd) )

# OCaml substitutions.
# Support tests for both native and bytecode builds.
config.substitutions.append( ('%ocamlc',
    "%s ocamlc -cclib -L%s %s" %
        (config.ocamlfind_executable, llvm_lib_dir, config.ocaml_flags)) )
if config.have_ocamlopt:
    config.substitutions.append( ('%ocamlopt',
        "%s ocamlopt -cclib -L%s -cclib -Wl,-rpath,%s %s" %
            (config.ocamlfind_executable, llvm_lib_dir, llvm_lib_dir, config.ocaml_flags)) )
else:
    config.substitutions.append( ('%ocamlopt', "true" ) )

# For each occurrence of an llvm tool name as its own word, replace it
# with the full path to the build directory holding that tool.  This
# ensures that we are testing the tools just built and not some random
# tools that might happen to be in the user's PATH.  Thus this list
# includes every tool placed in $(LLVM_OBJ_ROOT)/$(BuildMode)/bin
# (llvm_tools_dir in lit parlance).

# Avoid matching RUN line fragments that are actually part of
# path names or options or whatever.
# The regex is a pre-assertion to avoid matching a preceding
# dot, hyphen, carat, or slash (.foo, -foo, etc.).  Some patterns
# also have a post-assertion to not match a trailing hyphen (foo-).
NOJUNK = r"(?<!\.|-|\^|/|<)"


def find_tool_substitution(pattern):
    # Extract the tool name from the pattern.  This relies on the tool
    # name being surrounded by \b word match operators.  If the
    # pattern starts with "| ", include it in the string to be
    # substituted.
    tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
                          pattern)
    tool_pipe = tool_match.group(2)
    tool_name = tool_match.group(4)
    # Did the user specify the tool path + arguments? This allows things like
    # llvm-lit "-Dllc=llc -enable-misched -verify-machineinstrs"
    tool_path = lit_config.params.get(tool_name)
    if tool_path is None:
        tool_path = lit.util.which(tool_name, llvm_tools_dir)
        if tool_path is None:
            return tool_name, tool_path, tool_pipe
    if (tool_name == "llc" and
       'LLVM_ENABLE_MACHINE_VERIFIER' in os.environ and
       os.environ['LLVM_ENABLE_MACHINE_VERIFIER'] == "1"):
        tool_path += " -verify-machineinstrs"
    if (tool_name == "llvm-go"):
        tool_path += " go=" + config.go_executable
    return tool_name, tool_path, tool_pipe


for pattern in [r"\bbugpoint\b(?!-)",
                NOJUNK + r"\bllc\b",
                r"\blli\b",
                r"\bllvm-ar\b",
                r"\bllvm-as\b",
                r"\bllvm-bcanalyzer\b",
                r"\bllvm-config\b",
                r"\bllvm-cov\b",
                r"\bllvm-cxxdump\b",
                r"\bllvm-diff\b",
                r"\bllvm-dis\b",
                r"\bllvm-dsymutil\b",
                r"\bllvm-dwarfdump\b",
                r"\bllvm-extract\b",
                r"\bllvm-lib\b",
                r"\bllvm-link\b",
                r"\bllvm-lto\b",
                r"\bllvm-lto2\b",
                r"\bllvm-mc\b",
                r"\bllvm-mcmarkup\b",
                r"\bllvm-modextract\b",
                r"\bllvm-nm\b",
                r"\bllvm-objdump\b",
                r"\bllvm-pdbutil\b",
                r"\bllvm-profdata\b",
                r"\bllvm-ranlib\b",
                r"\bllvm-readobj\b",
                r"\bllvm-rtdyld\b",
                r"\bllvm-size\b",
                r"\bllvm-split\b",
                r"\bllvm-strings\b",
                r"\bllvm-tblgen\b",
                r"\bllvm-c-test\b",
                r"\bllvm-cxxfilt\b",
                r"\bllvm-xray\b",
                NOJUNK + r"\bllvm-symbolizer\b",
                NOJUNK + r"\bopt\b",
                r"\bFileCheck\b",
                r"\bobj2yaml\b",
                NOJUNK + r"\bsancov\b",
                NOJUNK + r"\bsanstats\b",
                r"\byaml2obj\b",
                r"\byaml-bench\b",
                r"\bverify-uselistorder\b",
                # Handle these specially as they are strings searched
                # for during testing.
                r"\| \bcount\b",
                r"\| \bnot\b"]:
    tool_name, tool_path, tool_pipe = find_tool_substitution(pattern)
    if not tool_path:
        # Warn, but still provide a substitution.
        lit_config.note('Did not find ' + tool_name + ' in ' + llvm_tools_dir)
        tool_path = llvm_tools_dir + '/' + tool_name
    config.substitutions.append((pattern, tool_pipe + tool_path))

# For tools that are optional depending on the config, we won't warn
# if they're missing.
for pattern in [r"\bllvm-go\b",
                r"\bKaleidoscope-Ch3\b",
                r"\bKaleidoscope-Ch4\b",
                r"\bKaleidoscope-Ch5\b",
                r"\bKaleidoscope-Ch6\b",
                r"\bKaleidoscope-Ch7\b",
                r"\bKaleidoscope-Ch8\b"]:
    tool_name, tool_path, tool_pipe = find_tool_substitution(pattern)
    if not tool_path:
        # Provide a substitution anyway, for the sake of consistent errors.
        tool_path = llvm_tools_dir + '/' + tool_name
    config.substitutions.append((pattern, tool_pipe + tool_path))


### Targets

config.targets = frozenset(config.targets_to_build.split())

for arch in config.targets_to_build.split():
    config.available_features.add(arch.lower() + '-registered-target')

### Features

# Shell execution
if execute_external:
    config.available_features.add('shell')

# Others/can-execute.txt
if sys.platform not in ['win32']:
    config.available_features.add('can-execute')
    config.available_features.add('not_COFF')

# Loadable module
# FIXME: This should be supplied by Makefile or autoconf.
if sys.platform in ['win32', 'cygwin']:
    loadable_module = (config.enable_shared == 1)
else:
    loadable_module = True

if loadable_module:
    config.available_features.add('loadable_module')

# Static libraries are not built if BUILD_SHARED_LIBS is ON.
if not config.build_shared_libs:
    config.available_features.add("static-libs")

# Sanitizers.
if 'Address' in config.llvm_use_sanitizer:
    config.available_features.add("asan")
else:
    config.available_features.add("not_asan")
if 'Memory' in config.llvm_use_sanitizer:
    config.available_features.add("msan")
else:
    config.available_features.add("not_msan")
if 'Undefined' in config.llvm_use_sanitizer:
    config.available_features.add("ubsan")
else:
    config.available_features.add("not_ubsan")

# Check if we should run long running tests.
if lit_config.params.get("run_long_tests", None) == "true":
    config.available_features.add("long_tests")

# Direct object generation
if not 'hexagon' in config.target_triple:
    config.available_features.add("object-emission")

if config.have_zlib:
    config.available_features.add("zlib")
else:
    config.available_features.add("nozlib")

# LLVM can be configured with an empty default triple
# Some tests are "generic" and require a valid default triple
if config.target_triple:
    config.available_features.add("default_triple")
    if re.match(r'^x86_64.*-linux', config.target_triple):
      config.available_features.add("x86_64-linux")

# Native compilation: host arch == default triple arch
# FIXME: Consider cases that target can be executed
# even if host_triple were different from target_triple.
if config.host_triple == config.target_triple:
    config.available_features.add("native")

import subprocess

def have_ld_plugin_support():
    if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')):
        return False

    ld_cmd = subprocess.Popen([config.gold_executable, '--help'], stdout = subprocess.PIPE, env={'LANG': 'C'})
    ld_out = ld_cmd.stdout.read().decode()
    ld_cmd.wait()

    if not '-plugin' in ld_out:
        return False

    # check that the used emulations are supported.
    emu_line = [l for l in ld_out.split('\n') if 'supported emulations' in l]
    if len(emu_line) != 1:
        return False
    emu_line = emu_line[0]
    fields = emu_line.split(':')
    if len(fields) != 3:
        return False
    emulations = fields[2].split()
    if 'elf_x86_64' not in emulations:
        return False
    if 'elf32ppc' in emulations:
        config.available_features.add('ld_emu_elf32ppc')

    ld_version = subprocess.Popen([config.gold_executable, '--version'], stdout = subprocess.PIPE, env={'LANG': 'C'})
    if not 'GNU gold' in ld_version.stdout.read().decode():
        return False
    ld_version.wait()

    return True

if have_ld_plugin_support():
    config.available_features.add('ld_plugin')

def have_ld64_plugin_support():
    if not config.llvm_tool_lto_build or config.ld64_executable == '':
        return False

    ld_cmd = subprocess.Popen([config.ld64_executable, '-v'], stderr = subprocess.PIPE)
    ld_out = ld_cmd.stderr.read().decode()
    ld_cmd.wait()

    if 'ld64' not in ld_out or 'LTO' not in ld_out:
        return False

    return True

if have_ld64_plugin_support():
    config.available_features.add('ld64_plugin')

# Ask llvm-config about assertion mode.
try:
    llvm_config_cmd = subprocess.Popen(
        [os.path.join(llvm_tools_dir, 'llvm-config'), '--assertion-mode'],
        stdout = subprocess.PIPE,
        env=config.environment)
except OSError:
    print("Could not find llvm-config in " + llvm_tools_dir)
    exit(42)

if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
    config.available_features.add('asserts')
llvm_config_cmd.wait()

if 'darwin' == sys.platform:
    try:
        sysctl_cmd = subprocess.Popen(['sysctl', 'hw.optional.fma'],
                                    stdout = subprocess.PIPE)
    except OSError:
        print("Could not exec sysctl")
    result = sysctl_cmd.stdout.read().decode('ascii')
    if -1 != result.find("hw.optional.fma: 1"):
        config.available_features.add('fma3')
    sysctl_cmd.wait()

if platform.system() in ['Windows']:
    if re.match(r'.*-win32$', config.target_triple):
        config.available_features.add('target-windows')
    # For tests that require Windows to run.
    config.available_features.add('system-windows')

# .debug_frame is not emitted for targeting Windows x64.
if not re.match(r'^x86_64.*-(mingw32|windows-gnu|win32)', config.target_triple):
    config.available_features.add('debug_frame')

# Check if we should use gmalloc.
use_gmalloc_str = lit_config.params.get('use_gmalloc', None)
if use_gmalloc_str is not None:
    if use_gmalloc_str.lower() in ('1', 'true'):
        use_gmalloc = True
    elif use_gmalloc_str.lower() in ('', '0', 'false'):
        use_gmalloc = False
    else:
        lit_config.fatal('user parameter use_gmalloc should be 0 or 1')
else:
    # Default to not using gmalloc
    use_gmalloc = False

# Allow use of an explicit path for gmalloc library.
# Will default to '/usr/lib/libgmalloc.dylib' if not set.
gmalloc_path_str = lit_config.params.get('gmalloc_path',
                                         '/usr/lib/libgmalloc.dylib')

if use_gmalloc:
     config.environment.update({'DYLD_INSERT_LIBRARIES' : gmalloc_path_str})

# Ask llvm-config about global-isel.
try:
    llvm_config_cmd = subprocess.Popen(
        [os.path.join(llvm_tools_dir, 'llvm-config'), '--has-global-isel'],
        stdout = subprocess.PIPE,
        env=config.environment)
except OSError:
    print("Could not find llvm-config in " + llvm_tools_dir)
    exit(42)

if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
    config.available_features.add('global-isel')
llvm_config_cmd.wait()

if config.have_libxar:
    config.available_features.add('xar')

if config.enable_abi_breaking_checks == "1":
    config.available_features.add('abi-breaking-checks')
