445 lines · python
1# -*- Python -*-2 3import os4import platform5import re6import subprocess7import tempfile8 9import lit.formats10import lit.util11 12from lit.llvm import llvm_config13from lit.llvm.subst import ToolSubst14from lit.llvm.subst import FindTool15 16# Configuration file for the 'lit' test runner.17 18# name: The name of this test suite.19config.name = "Clang"20 21# TODO: Consolidate the logic for turning on the internal shell by default for all LLVM test suites.22# See https://github.com/llvm/llvm-project/issues/106636 for more details.23#24# We prefer the lit internal shell which provides a better user experience on failures25# and is faster unless the user explicitly disables it with LIT_USE_INTERNAL_SHELL=026# env var.27use_lit_shell = True28lit_shell_env = os.environ.get("LIT_USE_INTERNAL_SHELL")29if lit_shell_env:30 use_lit_shell = lit.util.pythonize_bool(lit_shell_env)31 32# testFormat: The test format to use to interpret tests.33#34# For now we require '&&' between commands, until they get globally killed and35# the test runner updated.36config.test_format = lit.formats.ShTest(execute_external=not use_lit_shell)37 38# suffixes: A list of file extensions to treat as test files.39config.suffixes = [40 ".c",41 ".cpp",42 ".i",43 ".cir",44 ".cppm",45 ".m",46 ".mm",47 ".cu",48 ".cuh",49 ".hip",50 ".hlsl",51 ".ll",52 ".cl",53 ".clcpp",54 ".s",55 ".S",56 ".modulemap",57 ".test",58 ".rs",59 ".ifs",60 ".rc",61]62 63# excludes: A list of directories to exclude from the testsuite. The 'Inputs'64# subdirectories contain auxiliary inputs for various tests in their parent65# directories.66config.excludes = [67 "Inputs",68 "CMakeLists.txt",69 "README.txt",70 "LICENSE.txt",71 "debuginfo-tests",72]73 74# test_source_root: The root path where tests are located.75config.test_source_root = os.path.dirname(__file__)76 77# test_exec_root: The root path where tests should be run.78config.test_exec_root = os.path.join(config.clang_obj_root, "test")79 80llvm_config.use_default_substitutions()81 82llvm_config.use_clang()83 84config.substitutions.append(("%src_dir", config.clang_src_dir))85 86config.substitutions.append(("%src_include_dir", config.clang_src_dir + "/include"))87 88config.substitutions.append(("%target_triple", config.target_triple))89 90config.substitutions.append(("%PATH%", config.environment["PATH"]))91 92 93# For each occurrence of a clang tool name, replace it with the full path to94# the build directory holding that tool. We explicitly specify the directories95# to search to ensure that we get the tools just built and not some random96# tools that might happen to be in the user's PATH.97tool_dirs = [config.clang_tools_dir, config.llvm_tools_dir]98 99tools = [100 "apinotes-test",101 "c-index-test",102 "cir-opt",103 "clang-diff",104 "clang-format",105 "clang-repl",106 "llvm-offload-binary",107 "clang-tblgen",108 "clang-scan-deps",109 "clang-installapi",110 "opt",111 "llvm-ifs",112 "yaml2obj",113 "clang-linker-wrapper",114 "clang-nvlink-wrapper",115 "clang-sycl-linker",116 "llvm-lto",117 "llvm-lto2",118 "llvm-profdata",119 "llvm-readtapi",120 ToolSubst(121 "%clang_extdef_map",122 command=FindTool("clang-extdef-mapping"),123 unresolved="ignore",124 ),125]126 127if config.clang_examples:128 config.available_features.add("examples")129 130 131def have_host_out_of_process_jit_feature_support():132 clang_repl_exe = lit.util.which("clang-repl", config.clang_tools_dir)133 134 if not clang_repl_exe:135 return False136 137 testcode = b"\n".join([b"int i = 0;", b"%quit"])138 139 try:140 clang_repl_cmd = subprocess.run(141 [clang_repl_exe, "-orc-runtime", "-oop-executor"],142 stdout=subprocess.PIPE,143 stderr=subprocess.PIPE,144 input=testcode,145 )146 except OSError:147 return False148 149 if clang_repl_cmd.returncode == 0:150 return True151 152 return False153 154 155def run_clang_repl(args):156 clang_repl_exe = lit.util.which("clang-repl", config.clang_tools_dir)157 158 if not clang_repl_exe:159 return ""160 161 try:162 clang_repl_cmd = subprocess.Popen(163 [clang_repl_exe, args], stdout=subprocess.PIPE164 )165 except OSError:166 print("could not exec clang-repl")167 return ""168 169 clang_repl_out = clang_repl_cmd.stdout.read().decode("ascii")170 clang_repl_cmd.wait()171 172 return clang_repl_out173 174 175def have_host_jit_feature_support(feature_name):176 return "true" in run_clang_repl("--host-supports-" + feature_name)177 178def have_host_clang_repl_cuda():179 clang_repl_exe = lit.util.which('clang-repl', config.clang_tools_dir)180 181 if not clang_repl_exe:182 return False183 184 testcode = b'\n'.join([185 b"__global__ void test_func() {}",186 b"test_func<<<1,1>>>();",187 b"extern \"C\" int puts(const char *s);",188 b"puts(cudaGetLastError() ? \"failure\" : \"success\");",189 b"%quit"190 ])191 try:192 clang_repl_cmd = subprocess.run([clang_repl_exe, '--cuda'],193 stdout=subprocess.PIPE,194 stderr=subprocess.PIPE,195 input=testcode)196 except OSError:197 return False198 199 if clang_repl_cmd.returncode == 0:200 if clang_repl_cmd.stdout.find(b"success") != -1:201 return True202 203 return False204 205if have_host_jit_feature_support('jit'):206 config.available_features.add('host-supports-jit')207 208 if have_host_clang_repl_cuda():209 config.available_features.add('host-supports-cuda')210 hosttriple = run_clang_repl("--host-jit-triple")211 config.substitutions.append(("%host-jit-triple", hosttriple.strip()))212 213 if have_host_out_of_process_jit_feature_support():214 config.available_features.add("host-supports-out-of-process-jit")215 216if config.clang_staticanalyzer:217 config.available_features.add("staticanalyzer")218 tools.append("clang-check")219 220 if config.clang_staticanalyzer_z3:221 config.available_features.add("z3")222 if config.clang_staticanalyzer_z3_mock:223 config.available_features.add("z3-mock")224 else:225 config.available_features.add("no-z3")226 227 check_analyzer_fixit_path = os.path.join(228 config.test_source_root, "Analysis", "check-analyzer-fixit.py"229 )230 config.substitutions.append(231 (232 "%check_analyzer_fixit",233 '"%s" %s' % (config.python_executable, check_analyzer_fixit_path),234 )235 )236 237 csv2json_path = os.path.join(config.test_source_root, "Analysis", "csv2json.py")238 config.substitutions.append(239 (240 "%csv2json",241 '"%s" %s' % (config.python_executable, csv2json_path),242 )243 )244 245# ClangIR support246if config.clang_enable_cir:247 config.available_features.add("cir-support")248 249llvm_config.add_tool_substitutions(tools, tool_dirs)250 251config.substitutions.append(252 (253 "%hmaptool",254 "'%s' %s"255 % (256 config.python_executable,257 os.path.join(config.clang_src_dir, "utils", "hmaptool", "hmaptool"),258 ),259 )260)261 262config.substitutions.append(263 (264 "%deps-to-rsp",265 '"%s" %s'266 % (267 config.python_executable,268 os.path.join(config.clang_src_dir, "utils", "module-deps-to-rsp.py"),269 ),270 )271)272 273# Determine whether the test target is compatible with execution on the host.274if "aarch64" in config.host_arch:275 config.available_features.add("aarch64-host")276 277# Some tests are sensitive to whether clang is statically or dynamically linked278# to other libraries.279if not (config.build_shared_libs or config.link_llvm_dylib or config.link_clang_dylib):280 config.available_features.add("static-libs")281 282# Plugins (loadable modules)283if config.has_plugins and config.llvm_plugin_ext:284 config.available_features.add("plugins")285 286if config.clang_default_pie_on_linux:287 config.available_features.add("default-pie-on-linux")288 289# Set available features we allow tests to conditionalize on.290#291if config.clang_default_cxx_stdlib != "":292 config.available_features.add(293 "default-cxx-stdlib={}".format(config.clang_default_cxx_stdlib)294 )295 296# As of 2011.08, crash-recovery tests still do not pass on FreeBSD.297if platform.system() not in ["FreeBSD"]:298 config.available_features.add("crash-recovery")299 300# ANSI escape sequences in non-dumb terminal301if platform.system() not in ["Windows"]:302 config.available_features.add("ansi-escape-sequences")303 304# Capability to print utf8 to the terminal.305# Windows expects codepage, unless Wide API.306if platform.system() not in ["Windows"]:307 config.available_features.add("utf8-capable-terminal")308 309# Support for libgcc runtime. Used to rule out tests that require310# clang to run with -rtlib=libgcc.311if platform.system() not in ["Darwin", "Fuchsia"]:312 config.available_features.add("libgcc")313 314# Case-insensitive file system315 316 317def is_filesystem_case_insensitive():318 os.makedirs(config.test_exec_root, exist_ok=True)319 handle, path = tempfile.mkstemp(prefix="case-test", dir=config.test_exec_root)320 isInsensitive = os.path.exists(321 os.path.join(os.path.dirname(path), os.path.basename(path).upper())322 )323 os.close(handle)324 os.remove(path)325 return isInsensitive326 327 328if is_filesystem_case_insensitive():329 config.available_features.add("case-insensitive-filesystem")330 331# Tests that require the /dev/fd filesystem.332if os.path.exists("/dev/fd/0") and sys.platform not in ["cygwin"]:333 config.available_features.add("dev-fd-fs")334 335# Set on native MS environment.336if re.match(r".*-(windows-msvc)$", config.target_triple):337 config.available_features.add("ms-sdk")338 339# [PR8833] LLP64-incompatible tests340if not re.match(341 r"^(aarch64|arm64ec|x86_64).*-(windows-msvc|windows-gnu)$", config.target_triple342):343 config.available_features.add("LP64")344 345# Tests that are specific to the Apple Silicon macOS.346if re.match(r"^arm64(e)?-apple-(macos|darwin)", config.target_triple):347 config.available_features.add("apple-silicon-mac")348 349# [PR18856] Depends to remove opened file. On win32, a file could be removed350# only if all handles were closed.351if platform.system() not in ["Windows"]:352 config.available_features.add("can-remove-opened-file")353 354# Features355known_arches = ["x86_64", "mips64", "ppc64", "aarch64"]356if any(config.target_triple.startswith(x) for x in known_arches):357 config.available_features.add("clang-target-64-bits")358 359 360def calculate_arch_features(arch_string):361 features = []362 for arch in arch_string.split():363 features.append(arch.lower() + "-registered-target")364 return features365 366 367llvm_config.feature_config(368 [369 ("--assertion-mode", {"ON": "asserts"}),370 ("--cxxflags", {r"-D_GLIBCXX_DEBUG\b": "libstdcxx-safe-mode"}),371 ("--targets-built", calculate_arch_features),372 ]373)374 375if lit.util.which("xmllint"):376 config.available_features.add("xmllint")377 378if config.enable_backtrace:379 config.available_features.add("backtrace")380 381if config.enable_threads:382 config.available_features.add("thread_support")383 384# Check if we should allow outputs to console.385run_console_tests = int(lit_config.params.get("enable_console", "0"))386if run_console_tests != 0:387 config.available_features.add("console")388 389lit.util.usePlatformSdkOnDarwin(config, lit_config)390macOSSDKVersion = lit.util.findPlatformSdkVersionOnMacOS(config, lit_config)391if macOSSDKVersion is not None:392 config.available_features.add("macos-sdk-" + str(macOSSDKVersion))393 394if os.path.exists("/etc/gentoo-release"):395 config.available_features.add("gentoo")396 397if config.enable_shared:398 config.available_features.add("enable_shared")399 400# Add a vendor-specific feature.401if config.clang_vendor_uti:402 config.available_features.add("clang-vendor=" + config.clang_vendor_uti)403 404if config.have_llvm_driver:405 config.available_features.add("llvm-driver")406 407 408# Some tests perform deep recursion, which requires a larger pthread stack size409# than the relatively low default of 192 KiB for 64-bit processes on AIX. The410# `AIXTHREAD_STK` environment variable provides a non-intrusive way to request411# a larger pthread stack size for the tests. Various applications and runtime412# libraries on AIX use a default pthread stack size of 4 MiB, so we will use413# that as a default value here.414if "AIXTHREAD_STK" in os.environ:415 config.environment["AIXTHREAD_STK"] = os.environ["AIXTHREAD_STK"]416elif platform.system() == "AIX":417 config.environment["AIXTHREAD_STK"] = "4194304"418 419# Some tools support an environment variable "OBJECT_MODE" on AIX OS, which420# controls the kind of objects they will support. If there is no "OBJECT_MODE"421# environment variable specified, the default behaviour is to support 32-bit422# objects only. In order to not affect most test cases, which expect to support423# 32-bit and 64-bit objects by default, set the environment variable424# "OBJECT_MODE" to "any" by default on AIX OS.425 426if "system-aix" in config.available_features:427 config.substitutions.append(("llvm-nm", "env OBJECT_MODE=any llvm-nm"))428 config.substitutions.append(("llvm-ar", "env OBJECT_MODE=any llvm-ar"))429 config.substitutions.append(("llvm-ranlib", "env OBJECT_MODE=any llvm-ranlib"))430 431# It is not realistically possible to account for all options that could432# possibly be present in system and user configuration files, so disable433# default configs for the test runs.434config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1"435 436if lit_config.update_tests:437 import sys438 import os439 440 utilspath = os.path.join(config.llvm_src_root, "utils")441 sys.path.append(utilspath)442 from update_any_test_checks import utc_lit_plugin443 444 lit_config.test_updaters.append(utc_lit_plugin)445