diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2019-04-30 10:53:39 -0700 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2019-05-03 10:36:50 -0700 |
commit | 541523eebab8f62b182643296deab26a47117f6f (patch) | |
tree | b5db369f05d6407125c9eee947adb96221844ab7 /mesonbuild/compilers/cpp.py | |
parent | 604b2534e8516e5ddade6d2d2514b3078275d711 (diff) | |
download | meson-541523eebab8f62b182643296deab26a47117f6f.zip meson-541523eebab8f62b182643296deab26a47117f6f.tar.gz meson-541523eebab8f62b182643296deab26a47117f6f.tar.bz2 |
compilers: Split C-Like functionality into a mixin classes
Currently C++ inherits C, which can lead to diamond problems. By pulling
the code out into a standalone mixin class that the C, C++, ObjC, and
Objc++ compilers can inherit and override as necessary we remove one
source of diamonding. I've chosen to split this out into it's own file
as the CLikeCompiler class is over 1000 lines by itself. This also
breaks the VisualStudio derived classes inheriting from each other, to
avoid the same C -> CPP inheritance problems. This is all one giant
patch because there just isn't a clean way to separate this.
I've done the same for Fortran since it effectively inherits the
CCompiler (I say effectively because was it actually did was gross
beyond explanation), it's probably not correct, but it seems to work for
now. There really is a lot of layering violation going on in the
Compilers, and a really good scrubbing would do this code a lot of good.
Diffstat (limited to 'mesonbuild/compilers/cpp.py')
-rw-r--r-- | mesonbuild/compilers/cpp.py | 83 |
1 files changed, 50 insertions, 33 deletions
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 2fd0b39..910a3e9 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -14,12 +14,12 @@ import functools import os.path +import typing from .. import coredata from .. import mlog from ..mesonlib import MesonException, version_compare -from .c import CCompiler, VisualStudioCCompiler, ClangClCCompiler from .compilers import ( gnu_winlibs, msvc_winlibs, @@ -31,20 +31,27 @@ from .compilers import ( ArmCompiler, ArmclangCompiler, CcrxCompiler, + Compiler, + VisualStudioLikeCompiler, ) -from .c_function_attributes import CXX_FUNC_ATTRIBUTES +from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES +from .clike import CLikeCompiler -class CPPCompiler(CCompiler): +class CPPCompiler(CLikeCompiler, Compiler): @classmethod def attribute_check_func(cls, name): - return CXX_FUNC_ATTRIBUTES.get(name, super().attribute_check_func(name)) + try: + return CXX_FUNC_ATTRIBUTES.get(name, C_FUNC_ATTRIBUTES[name]) + except KeyError: + raise MesonException('Unknown function attribute "{}"'.format(name)) - def __init__(self, exelist, version, is_cross, exe_wrap, **kwargs): + def __init__(self, exelist, version, is_cross: bool, + exe_wrap: typing.Optional[str] = None, **kwargs): # If a child ObjCPP class has already set it, don't set it ourselves - if not hasattr(self, 'language'): - self.language = 'cpp' - CCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs) + self.language = 'cpp' + Compiler.__init__(self, exelist, version, **kwargs) + CLikeCompiler.__init__(self, is_cross, exe_wrap) def get_display_language(self): return 'C++' @@ -322,25 +329,14 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler): return [] -class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler): - def __init__(self, exelist, version, is_cross, exe_wrap, target): - CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) - VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap, target) - self.base_options = ['b_pch', 'b_vscrt'] # FIXME add lto, pgo and the like +class VisualStudioLikeCPPCompilerMixin: - def get_options(self): - cpp_stds = ['none', 'c++11', 'vc++11'] - if self.id == 'clang-cl': - cpp_stds.extend(['c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest']) - else: - # Visual Studio 2015 and later - if version_compare(self.version, '>=19'): - cpp_stds.extend(['c++14', 'vc++14', 'c++latest', 'vc++latest']) - # Visual Studio 2017 and later - if version_compare(self.version, '>=19.11'): - cpp_stds.extend(['c++17', 'vc++17']) + """Mixin for C++ specific method overrides in MSVC-like compilers.""" - opts = CPPCompiler.get_options(self) + def get_option_link_args(self, options): + return options['cpp_winlibs'].value[:] + + def _get_options_impl(self, opts, cpp_stds: typing.List[str]): opts.update({'cpp_eh': coredata.UserComboOption('cpp_eh', 'C++ exception handling type.', ['none', 'a', 's', 'sc'], @@ -393,19 +389,40 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler): return args - def get_option_link_args(self, options): - return options['cpp_winlibs'].value[:] - def get_compiler_check_args(self): - # Visual Studio C++ compiler doesn't support -fpermissive, - # so just use the plain C args. - return VisualStudioCCompiler.get_compiler_check_args(self) + # XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class. + return CLikeCompiler.get_compiler_check_args(self) -class ClangClCPPCompiler(VisualStudioCPPCompiler, ClangClCCompiler): + +class VisualStudioCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler): def __init__(self, exelist, version, is_cross, exe_wrap, target): - VisualStudioCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, target) + CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) + VisualStudioLikeCompiler.__init__(self, target) + self.base_options = ['b_pch', 'b_vscrt'] # FIXME add lto, pgo and the like + self.id = 'msvc' + + def get_options(self): + cpp_stds = ['none', 'c++11', 'vc++11'] + # Visual Studio 2015 and later + if version_compare(self.version, '>=19'): + cpp_stds.extend(['c++14', 'vc++14', 'c++latest', 'vc++latest']) + # Visual Studio 2017 and later + if version_compare(self.version, '>=19.11'): + cpp_stds.extend(['c++17', 'vc++17']) + return self._get_options_impl(super().get_options(), cpp_stds) + + +class ClangClCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler): + def __init__(self, exelist, version, is_cross, exe_wrap, target): + CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) + VisualStudioLikeCompiler.__init__(self, target) self.id = 'clang-cl' + def get_options(self): + cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'] + return self._get_options_impl(super().get_options(), cpp_stds) + + class ArmCPPCompiler(ArmCompiler, CPPCompiler): def __init__(self, exelist, version, compiler_type, is_cross, exe_wrap=None, **kwargs): CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs) |