# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import sys
import re
import platform

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 = lit.util.capture(['llvm-config', '--src-root']).strip()
    llvm_obj_root = lit.util.capture(['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-pdbdump\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')
