Adjust libc++ test infastructure to fully support modules
This patch overhalls the libc++ test format/configuration in order to fully support modules. By "fully support" I mean get almost all of the tests passing. The main hurdle for doing this is handling tests that `#define _LIBCPP_FOO` macros to test a different configuration. This patch deals with these tests in the following ways: 1. For tests that define single `_LIBCPP_ABI_FOO` macros have been annotated with `// MODULES_DEFINES: _LIBCPP_ABI_FOO`. This allows the test suite to define the macro on the command line so it uses a different set of modules. 2. Tests for libc++'s debug mode (which define custom `_LIBCPP_ASSERT`) are automatically detected by the test suite and are compiled and run with modules disabled. This patch also cleans up how the `CXXCompiler` helper class handles enabling/disabling language features. NOTE: This patch uses `LIT` features which were only committed to LLVM today. If this patch breaks running the libc++ tests you probably need to update LLVM. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@288728 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#
|
||||
#===----------------------------------------------------------------------===##
|
||||
|
||||
import platform
|
||||
import os
|
||||
import lit.util
|
||||
import libcxx.util
|
||||
@@ -19,16 +20,47 @@ class CXXCompiler(object):
|
||||
CM_Link = 3
|
||||
|
||||
def __init__(self, path, flags=None, compile_flags=None, link_flags=None,
|
||||
use_ccache=False):
|
||||
warning_flags=None, modules_flags=None, use_modules=False,
|
||||
use_ccache=False, use_warnings=False, compile_env=None,
|
||||
cxx_type=None, cxx_version=None):
|
||||
self.path = path
|
||||
self.flags = list(flags or [])
|
||||
self.compile_flags = list(compile_flags or [])
|
||||
self.warning_flags = []
|
||||
self.warning_flags = list(warning_flags or [])
|
||||
self.link_flags = list(link_flags or [])
|
||||
self.modules_flags = list(modules_flags or [])
|
||||
self.use_modules = use_modules
|
||||
assert not use_modules or modules_flags is not None
|
||||
self.use_ccache = use_ccache
|
||||
self.type = None
|
||||
self.version = None
|
||||
self._initTypeAndVersion()
|
||||
self.use_warnings = use_warnings
|
||||
if compile_env is not None:
|
||||
self.compile_env = dict(compile_env)
|
||||
else:
|
||||
self.compile_env = None
|
||||
self.type = cxx_type
|
||||
self.version = cxx_version
|
||||
if self.type is None or self.version is None:
|
||||
self._initTypeAndVersion()
|
||||
|
||||
def copy(self):
|
||||
new_cxx = CXXCompiler(
|
||||
self.path, flags=self.flags, compile_flags=self.compile_flags,
|
||||
link_flags=self.link_flags, warning_flags=self.warning_flags,
|
||||
modules_flags=self.modules_flags, use_modules=self.use_modules,
|
||||
use_ccache=self.use_ccache, use_warnings=self.use_warnings,
|
||||
compile_env=self.compile_env, cxx_type=self.type,
|
||||
cxx_version=self.version)
|
||||
return new_cxx
|
||||
|
||||
def useModules(self, value=True):
|
||||
self.use_modules = value
|
||||
assert not self.use_modules or self.modules_flags is not None
|
||||
|
||||
def useCCache(self, value=True):
|
||||
self.use_ccache = value
|
||||
|
||||
def useWarnings(self, value=True):
|
||||
self.use_warnings = value
|
||||
|
||||
def _initTypeAndVersion(self):
|
||||
# Get compiler type and version
|
||||
@@ -54,10 +86,9 @@ class CXXCompiler(object):
|
||||
self.version = (major_ver, minor_ver, patchlevel)
|
||||
|
||||
def _basicCmd(self, source_files, out, mode=CM_Default, flags=[],
|
||||
input_is_cxx=False,
|
||||
enable_warnings=True, disable_ccache=False):
|
||||
input_is_cxx=False):
|
||||
cmd = []
|
||||
if self.use_ccache and not disable_ccache \
|
||||
if self.use_ccache \
|
||||
and not mode == self.CM_Link \
|
||||
and not mode == self.CM_PreProcess:
|
||||
cmd += ['ccache']
|
||||
@@ -77,68 +108,64 @@ class CXXCompiler(object):
|
||||
elif mode == self.CM_Compile:
|
||||
cmd += ['-c']
|
||||
cmd += self.flags
|
||||
if self.use_modules:
|
||||
cmd += self.modules_flags
|
||||
if mode != self.CM_Link:
|
||||
cmd += self.compile_flags
|
||||
if enable_warnings:
|
||||
if self.use_warnings:
|
||||
cmd += self.warning_flags
|
||||
if mode != self.CM_PreProcess and mode != self.CM_Compile:
|
||||
cmd += self.link_flags
|
||||
cmd += flags
|
||||
return cmd
|
||||
|
||||
def _getWarningFlags(self, enable_warnings=True):
|
||||
return self.warning_flags if enable_warnings else []
|
||||
def _getWarningFlags(self):
|
||||
return self.warning_flags if self.use_warnings else []
|
||||
|
||||
def preprocessCmd(self, source_files, out=None, flags=[],
|
||||
enable_warnings=True):
|
||||
def preprocessCmd(self, source_files, out=None, flags=[]):
|
||||
return self._basicCmd(source_files, out, flags=flags,
|
||||
mode=self.CM_PreProcess,
|
||||
enable_warnings=enable_warnings,
|
||||
input_is_cxx=True)
|
||||
|
||||
def compileCmd(self, source_files, out=None, flags=[],
|
||||
disable_ccache=False, enable_warnings=True):
|
||||
def compileCmd(self, source_files, out=None, flags=[]):
|
||||
return self._basicCmd(source_files, out, flags=flags,
|
||||
mode=self.CM_Compile,
|
||||
input_is_cxx=True,
|
||||
enable_warnings=enable_warnings,
|
||||
disable_ccache=disable_ccache) + ['-c']
|
||||
input_is_cxx=True) + ['-c']
|
||||
|
||||
def linkCmd(self, source_files, out=None, flags=[]):
|
||||
return self._basicCmd(source_files, out, mode=self.CM_Link)
|
||||
|
||||
def compileLinkCmd(self, source_files, out=None, flags=[],
|
||||
enable_warnings=True):
|
||||
return self._basicCmd(source_files, out, flags=flags,
|
||||
enable_warnings=enable_warnings)
|
||||
mode=self.CM_Link)
|
||||
|
||||
def preprocess(self, source_files, out=None, flags=[], env=None, cwd=None):
|
||||
def compileLinkCmd(self, source_files, out=None, flags=[]):
|
||||
return self._basicCmd(source_files, out, flags=flags)
|
||||
|
||||
def preprocess(self, source_files, out=None, flags=[], cwd=None):
|
||||
cmd = self.preprocessCmd(source_files, out, flags)
|
||||
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
|
||||
out, err, rc = lit.util.executeCommand(cmd, env=self.compile_env,
|
||||
cwd=cwd)
|
||||
return cmd, out, err, rc
|
||||
|
||||
def compile(self, source_files, out=None, flags=[], env=None, cwd=None,
|
||||
disable_ccache=False, enable_warnings=True):
|
||||
cmd = self.compileCmd(source_files, out, flags,
|
||||
disable_ccache=disable_ccache,
|
||||
enable_warnings=enable_warnings)
|
||||
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
|
||||
def compile(self, source_files, out=None, flags=[], cwd=None):
|
||||
cmd = self.compileCmd(source_files, out, flags)
|
||||
out, err, rc = lit.util.executeCommand(cmd, env=self.compile_env,
|
||||
cwd=cwd)
|
||||
return cmd, out, err, rc
|
||||
|
||||
def link(self, source_files, out=None, flags=[], env=None, cwd=None):
|
||||
def link(self, source_files, out=None, flags=[], cwd=None):
|
||||
cmd = self.linkCmd(source_files, out, flags)
|
||||
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
|
||||
out, err, rc = lit.util.executeCommand(cmd, env=self.compile_env,
|
||||
cwd=cwd)
|
||||
return cmd, out, err, rc
|
||||
|
||||
def compileLink(self, source_files, out=None, flags=[], env=None,
|
||||
def compileLink(self, source_files, out=None, flags=[],
|
||||
cwd=None):
|
||||
cmd = self.compileLinkCmd(source_files, out, flags)
|
||||
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
|
||||
out, err, rc = lit.util.executeCommand(cmd, env=self.compile_env,
|
||||
cwd=cwd)
|
||||
return cmd, out, err, rc
|
||||
|
||||
def compileLinkTwoSteps(self, source_file, out=None, object_file=None,
|
||||
flags=[], env=None, cwd=None,
|
||||
disable_ccache=False):
|
||||
flags=[], cwd=None):
|
||||
if not isinstance(source_file, str):
|
||||
raise TypeError('This function only accepts a single input file')
|
||||
if object_file is None:
|
||||
@@ -149,22 +176,20 @@ class CXXCompiler(object):
|
||||
with_fn = lambda: libcxx.util.nullContext(object_file)
|
||||
with with_fn() as object_file:
|
||||
cc_cmd, cc_stdout, cc_stderr, rc = self.compile(
|
||||
source_file, object_file, flags=flags, env=env, cwd=cwd,
|
||||
disable_ccache=disable_ccache)
|
||||
source_file, object_file, flags=flags, cwd=cwd)
|
||||
if rc != 0:
|
||||
return cc_cmd, cc_stdout, cc_stderr, rc
|
||||
|
||||
link_cmd, link_stdout, link_stderr, rc = self.link(
|
||||
object_file, out=out, flags=flags, env=env, cwd=cwd)
|
||||
object_file, out=out, flags=flags, cwd=cwd)
|
||||
return (cc_cmd + ['&&'] + link_cmd, cc_stdout + link_stdout,
|
||||
cc_stderr + link_stderr, rc)
|
||||
|
||||
def dumpMacros(self, source_files=None, flags=[], env=None, cwd=None):
|
||||
def dumpMacros(self, source_files=None, flags=[], cwd=None):
|
||||
if source_files is None:
|
||||
source_files = os.devnull
|
||||
flags = ['-dM'] + flags
|
||||
cmd, out, err, rc = self.preprocess(source_files, flags=flags, env=env,
|
||||
cwd=cwd)
|
||||
cmd, out, err, rc = self.preprocess(source_files, flags=flags, cwd=cwd)
|
||||
if rc != 0:
|
||||
return None
|
||||
parsed_macros = {}
|
||||
@@ -215,11 +240,11 @@ class CXXCompiler(object):
|
||||
else:
|
||||
return False
|
||||
|
||||
def addWarningFlagIfSupported(self, flag):
|
||||
def hasWarningFlag(self, flag):
|
||||
"""
|
||||
addWarningFlagIfSupported - Add a warning flag if the compiler
|
||||
supports it. Unlike addCompileFlagIfSupported, this function detects
|
||||
when "-Wno-<warning>" flags are unsupported. If flag is a
|
||||
hasWarningFlag - Test if the compiler supports a given warning flag.
|
||||
Unlike addCompileFlagIfSupported, this function detects when
|
||||
"-Wno-<warning>" flags are unsupported. If flag is a
|
||||
"-Wno-<warning>" GCC will not emit an unknown option diagnostic unless
|
||||
another error is triggered during compilation.
|
||||
"""
|
||||
@@ -230,7 +255,10 @@ class CXXCompiler(object):
|
||||
return True
|
||||
return False
|
||||
flags = ['-Werror', flag]
|
||||
cmd = self.compileCmd('-', os.devnull, flags, enable_warnings=False)
|
||||
old_use_warnings = self.use_warnings
|
||||
self.useWarnings(False)
|
||||
cmd = self.compileCmd('-', os.devnull, flags)
|
||||
self.useWarnings(True)
|
||||
# Remove '-v' because it will cause the command line invocation
|
||||
# to be printed as part of the error output.
|
||||
# TODO(EricWF): Are there other flags we need to worry about?
|
||||
@@ -240,5 +268,10 @@ class CXXCompiler(object):
|
||||
assert rc != 0
|
||||
if flag in err:
|
||||
return False
|
||||
self.warning_flags += [flag]
|
||||
return True
|
||||
|
||||
def addWarningFlagIfSupported(self, flag):
|
||||
if self.hasWarningFlag(flag):
|
||||
self.warning_flags += [flag]
|
||||
return True
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user