aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers/cpp.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2019-04-30 10:53:39 -0700
committerDylan Baker <dylan@pnwbakers.com>2019-05-03 10:36:50 -0700
commit541523eebab8f62b182643296deab26a47117f6f (patch)
treeb5db369f05d6407125c9eee947adb96221844ab7 /mesonbuild/compilers/cpp.py
parent604b2534e8516e5ddade6d2d2514b3078275d711 (diff)
downloadmeson-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.py83
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)