# SPDX-License-Identifier: Apache-2.0
# Copyright 2012-2017 The Meson development team

from __future__ import annotations

import functools
import os.path
import typing as T

from .. import options
from .. import mlog
from ..mesonlib import MesonException, version_compare, lazy_property

from .compilers import (
    gnu_winlibs,
    msvc_winlibs,
    Compiler,
    CompileCheckMode,
)
from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES
from .mixins.apple import AppleCompilerMixin, AppleCPPStdsMixin
from .mixins.clike import CLikeCompiler
from .mixins.ccrx import CcrxCompiler
from .mixins.ti import TICompiler
from .mixins.arm import ArmCompiler, ArmclangCompiler
from .mixins.visualstudio import MSVCCompiler, ClangClCompiler
from .mixins.gnu import GnuCompiler, GnuCPPStds, gnu_common_warning_args, gnu_cpp_warning_args
from .mixins.intel import IntelGnuLikeCompiler, IntelLLVMLikeCompiler, IntelVisualStudioLikeCompiler
from .mixins.clang import ClangCompiler, ClangCPPStds
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.emscripten import EmscriptenMixin
from .mixins.metrowerks import MetrowerksCompiler
from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args
from .mixins.microchip import Xc32Compiler, Xc32CPPStds

if T.TYPE_CHECKING:
    from ..options import MutableKeyedOptionDictType
    from ..dependencies import Dependency
    from ..environment import Environment
    from ..linkers.linkers import DynamicLinker
    from ..mesonlib import MachineChoice
    from ..build import BuildTarget
    CompilerMixinBase = CLikeCompiler
else:
    CompilerMixinBase = object

ALL_STDS = ['c++98', 'c++0x', 'c++03', 'c++1y', 'c++1z', 'c++11', 'c++14', 'c++17']
ALL_STDS += ['c++2a', 'c++2b', 'c++2c', 'c++20', 'c++23', 'c++26']
ALL_STDS += [f'gnu{std[1:]}' for std in ALL_STDS]
ALL_STDS += ['vc++11', 'vc++14', 'vc++17', 'vc++20', 'vc++23', 'vc++latest', 'c++latest']


def non_msvc_eh_options(eh: str, args: T.List[str]) -> None:
    if eh == 'none':
        args.append('-fno-exceptions')
    elif eh in {'s', 'c'}:
        mlog.warning(f'non-MSVC compilers do not support {eh} exception handling. '
                     'You may want to set eh to \'default\'.', fatal=False)

class CPPCompiler(CLikeCompiler, Compiler):
    def attribute_check_func(self, name: str) -> str:
        try:
            return CXX_FUNC_ATTRIBUTES.get(name, C_FUNC_ATTRIBUTES[name])
        except KeyError:
            raise MesonException(f'Unknown function attribute "{name}"')

    language = 'cpp'

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        # If a child ObjCPP class has already set it, don't set it ourselves
        Compiler.__init__(self, ccache, exelist, version, for_machine, env,
                          linker=linker, full_version=full_version)
        CLikeCompiler.__init__(self)

    @classmethod
    def get_display_language(cls) -> str:
        return 'C++'

    def get_no_stdinc_args(self) -> T.List[str]:
        return ['-nostdinc++']

    def get_no_stdlib_link_args(self) -> T.List[str]:
        return ['-nostdlib++']

    def get_cpp_modules_args(self) -> T.List[str]:
        return []

    def _sanity_check_source_code(self) -> str:
        return '#include <stddef.h>\nclass breakCCompiler;int main(void) { return 0; }\n'

    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
        # -fpermissive allows non-conforming code to compile which is necessary
        # for many C++ checks. Particularly, the has_header_symbol check is
        # too strict without this and always fails.
        return super().get_compiler_check_args(mode) + ['-fpermissive']

    def has_header_symbol(self, hname: str, symbol: str, prefix: str, *,
                          extra_args: T.Union[None, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]] = None,
                          dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]:
        # Check if it's a C-like symbol
        found, cached = super().has_header_symbol(hname, symbol, prefix,
                                                  extra_args=extra_args,
                                                  dependencies=dependencies)
        if found:
            return True, cached
        # Check if it's a class or a template
        if extra_args is None:
            extra_args = []
        t = f'''{prefix}
        #include <{hname}>
        using {symbol};
        int main(void) {{ return 0; }}'''
        return self.compiles(t, extra_args=extra_args,
                             dependencies=dependencies)

    def _test_cpp_std_arg(self, cpp_std_value: str) -> bool:
        # Test whether the compiler understands a -std=XY argument
        assert cpp_std_value.startswith('-std=')

        # This test does not use has_multi_arguments() for two reasons:
        # 1. has_multi_arguments() requires an env argument, which the compiler
        #    object does not have at this point.
        # 2. even if it did have an env object, that might contain another more
        #    recent -std= argument, which might lead to a cascaded failure.
        CPP_TEST = 'int i = static_cast<int>(0);'
        with self.compile(CPP_TEST, extra_args=[cpp_std_value], mode=CompileCheckMode.COMPILE) as p:
            if p.returncode == 0:
                mlog.debug(f'Compiler accepts {cpp_std_value}:', 'YES')
                return True
            else:
                mlog.debug(f'Compiler accepts {cpp_std_value}:', 'NO')
                return False

    @functools.lru_cache()
    def _find_best_cpp_std(self, cpp_std: str) -> str:
        # The initial version mapping approach to make falling back
        # from '-std=c++14' to '-std=c++1y' was too brittle. For instance,
        # Apple's Clang uses a different versioning scheme to upstream LLVM,
        # making the whole detection logic awfully brittle. Instead, let's
        # just see if feeding GCC or Clang our '-std=' setting works, and
        # if not, try the fallback argument.
        CPP_FALLBACKS = {
            'c++11': 'c++0x',
            'gnu++11': 'gnu++0x',
            'c++14': 'c++1y',
            'gnu++14': 'gnu++1y',
            'c++17': 'c++1z',
            'gnu++17': 'gnu++1z',
            'c++20': 'c++2a',
            'gnu++20': 'gnu++2a',
            'c++23': 'c++2b',
            'gnu++23': 'gnu++2b',
            'c++26': 'c++2c',
            'gnu++26': 'gnu++2c',
        }

        # Currently, remapping is only supported for Clang, Elbrus and GCC
        assert self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten', 'armltdclang', 'intel-llvm', 'nvidia_hpc', 'xc32-gcc'])

        if cpp_std not in CPP_FALLBACKS:
            # 'c++03' and 'c++98' don't have fallback types
            return '-std=' + cpp_std

        for i in (cpp_std, CPP_FALLBACKS[cpp_std]):
            cpp_std_value = '-std=' + i
            if self._test_cpp_std_arg(cpp_std_value):
                return cpp_std_value

        raise MesonException(f'C++ Compiler does not support -std={cpp_std}')

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()
        key = self.form_compileropt_key('std')
        opts.update({
            key: options.UserStdOption('cpp', ALL_STDS),
        })
        return opts


class _StdCPPLibMixin(CompilerMixinBase):

    """Detect whether to use libc++ or libstdc++."""

    @lazy_property
    def language_stdlib_provider(self) -> str:
        # https://stackoverflow.com/a/31658120
        header = 'version' if self.has_header('version', '')[0] else 'ciso646'
        is_libcxx = self.has_header_symbol(header, '_LIBCPP_VERSION', '')[0]
        lib = 'c++' if is_libcxx else 'stdc++'
        return lib

    @functools.lru_cache(None)
    def language_stdlib_only_link_flags(self) -> T.List[str]:
        """Detect the C++ stdlib and default search dirs

        As an optimization, this method will cache the value, to avoid building the same values over and over

        :raises MesonException: If a stdlib cannot be determined
        """

        # We need to apply the search prefix here, as these link arguments may
        # be passed to a different compiler with a different set of default
        # search paths, such as when using Clang for C/C++ and gfortran for
        # fortran.
        search_dirs = [f'-L{d}' for d in self.get_compiler_dirs('libraries')]

        lib = self.language_stdlib_provider
        if self.find_library(lib, []) is not None:
            return search_dirs + [f'-l{lib}']

        # TODO: maybe a bug exception?
        raise MesonException('Could not detect either libc++ or libstdc++ as your C++ stdlib implementation.')


class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler):

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 defines: T.Optional[T.Dict[str, str]] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        ClangCompiler.__init__(self, defines)
        default_warn_args = ['-Wall', '-Winvalid-pch']
        self.warn_args = {'0': [],
                          '1': default_warn_args,
                          '2': default_warn_args + ['-Wextra'],
                          '3': default_warn_args + ['-Wextra', '-Wpedantic'],
                          'everything': ['-Weverything']}

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()

        key = self.form_compileropt_key('eh')
        opts[key] = options.UserComboOption(
            self.make_option_name(key),
            'C++ exception handling type.',
            'default',
            choices=['none', 'default', 'a', 's', 'sc'])

        key = self.form_compileropt_key('rtti')
        opts[key] = options.UserBooleanOption(
            self.make_option_name(key),
            'Enable RTTI',
            True)

        key = self.form_compileropt_key('debugstl')
        opts[key] = options.UserBooleanOption(
            self.make_option_name(key),
            'STL debug mode',
            False)

        if self.info.is_windows() or self.info.is_cygwin():
            key = self.form_compileropt_key('winlibs')
            opts[key] = options.UserStringArrayOption(
                self.make_option_name(key),
                'Standard Win libraries to link against',
                gnu_winlibs)
        return opts

    def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []

        rtti = self.get_compileropt_value('rtti', target, subproject)
        debugstl = self.get_compileropt_value('debugstl', target, subproject)
        eh = self.get_compileropt_value('eh', target, subproject)

        assert isinstance(rtti, bool)
        assert isinstance(eh, str)
        assert isinstance(debugstl, bool)

        non_msvc_eh_options(eh, args)

        if debugstl:
            args.append('-D_GLIBCXX_DEBUG=1')

            # We can't do _LIBCPP_DEBUG because it's unreliable unless libc++ was built with it too:
            # https://discourse.llvm.org/t/building-a-program-with-d-libcpp-debug-1-against-a-libc-that-is-not-itself-built-with-that-define/59176/3
            # Note that unlike _GLIBCXX_DEBUG, _MODE_DEBUG doesn't break ABI. It's just slow.
            if version_compare(self.version, '>=18'):
                args.append('-U_LIBCPP_HARDENING_MODE')
                args.append('-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG')

        if not rtti:
            args.append('-fno-rtti')

        return args

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append(self._find_best_cpp_std(std))
        return args

    def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        if self.info.is_windows() or self.info.is_cygwin():
            # without a typedict mypy can't understand this.
            retval = self.get_compileropt_value('winlibs', target, subproject)
            assert isinstance(retval, list)
            libs = retval[:]
            for l in libs:
                assert isinstance(l, str)
            return libs
        return []

    def get_assert_args(self, disable: bool) -> T.List[str]:
        if disable:
            return ['-DNDEBUG']

        # Don't inject the macro if the compiler already has it pre-defined.
        for macro in ['_GLIBCXX_ASSERTIONS', '_LIBCPP_HARDENING_MODE', '_LIBCPP_ENABLE_ASSERTIONS']:
            if self.defines.get(macro) is not None:
                return []

        if self.language_stdlib_provider == 'stdc++':
            return ['-D_GLIBCXX_ASSERTIONS=1']

        return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST']

    def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
        args = super().get_pch_use_args(pch_dir, header)
        if version_compare(self.version, '>=11'):
            return ['-fpch-instantiate-templates'] + args
        return args

    def get_cpp_modules_args(self) -> T.List[str]:
        # Although -fmodules-ts is removed in LLVM 17, we keep this in for compatibility with old compilers.
        return ['-fmodules', '-fmodules-ts']


class ArmLtdClangCPPCompiler(ClangCPPCompiler):

    id = 'armltdclang'


class AppleClangCPPCompiler(AppleCompilerMixin, AppleCPPStdsMixin, ClangCPPCompiler):
    pass


class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler):

    id = 'emscripten'

    # Emscripten uses different version numbers than Clang; `emcc -v` will show
    # the Clang version number used as well (but `emcc --version` does not).
    # See https://github.com/pyodide/pyodide/discussions/4762 for more on
    # emcc <--> clang versions. Note, although earlier versions claim to be the
    # Clang versions 12.0.0 and 17.0.0 required for these C++ standards, they
    # only accept the flags in the later versions below.
    _CPP23_VERSION = '>=2.0.10'
    _CPP26_VERSION = '>=3.1.39'

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 defines: T.Optional[T.Dict[str, str]] = None,
                 full_version: T.Optional[str] = None):
        if not env.is_cross_build(for_machine):
            raise MesonException('Emscripten compiler can only be used for cross compilation.')
        if not version_compare(version, '>=1.39.19'):
            raise MesonException('Meson requires Emscripten >= 1.39.19')
        ClangCPPCompiler.__init__(self, ccache, exelist, version, for_machine, env,
                                  linker=linker, defines=defines, full_version=full_version)

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append(self._find_best_cpp_std(std))
        return args


class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
    '''
    Keil armclang
    '''

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        ArmclangCompiler.__init__(self)
        default_warn_args = ['-Wall', '-Winvalid-pch']
        self.warn_args = {'0': [],
                          '1': default_warn_args,
                          '2': default_warn_args + ['-Wextra'],
                          '3': default_warn_args + ['-Wextra', '-Wpedantic'],
                          'everything': ['-Weverything']}

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()

        key = self.form_compileropt_key('eh')
        opts[key] = options.UserComboOption(
            self.make_option_name(key),
            'C++ exception handling type.',
            'default',
            choices=['none', 'default', 'a', 's', 'sc'])

        key = self.form_compileropt_key('std')
        std_opt = opts[key]
        assert isinstance(std_opt, options.UserStdOption), 'for mypy'
        std_opt.set_versions(['c++98', 'c++03', 'c++11', 'c++14', 'c++17'], gnu=True)
        return opts

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append('-std=' + std)

        eh = self.get_compileropt_value('eh', target, subproject)
        assert isinstance(eh, str)
        non_msvc_eh_options(eh, args)

        return args

    def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        return []


class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler):
    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 defines: T.Optional[T.Dict[str, str]] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        GnuCompiler.__init__(self, defines)
        default_warn_args = ['-Wall', '-Winvalid-pch']
        self.warn_args = {'0': [],
                          '1': default_warn_args,
                          '2': default_warn_args + ['-Wextra'],
                          '3': default_warn_args + ['-Wextra', '-Wpedantic'],
                          'everything': (default_warn_args + ['-Wextra', '-Wpedantic'] +
                                         self.supported_warn_args(gnu_common_warning_args) +
                                         self.supported_warn_args(gnu_cpp_warning_args))}

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()

        key = self.form_compileropt_key('eh')
        opts[key] = options.UserComboOption(
            self.make_option_name(key),
            'C++ exception handling type.',
            'default',
            choices=['none', 'default', 'a', 's', 'sc'])

        key = self.form_compileropt_key('rtti')
        opts[key] = options.UserBooleanOption(
            self.make_option_name(key),
            'Enable RTTI',
            True)

        key = self.form_compileropt_key('debugstl')
        opts[key] = options.UserBooleanOption(
            self.make_option_name(key),
            'STL debug mode',
            False)

        if self.info.is_windows() or self.info.is_cygwin():
            key = key.evolve(name='cpp_winlibs')
            opts[key] = options.UserStringArrayOption(
                self.make_option_name(key),
                'Standard Win libraries to link against',
                gnu_winlibs)

        if version_compare(self.version, '>=15.1'):
            key = key.evolve(name='cpp_importstd')
            opts[key] = options.UserComboOption(self.make_option_name(key),
                                                'Use #import std.',
                                                'false',
                                                choices=['false', 'true'])

        return opts

    def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []

        rtti = self.get_compileropt_value('rtti', target, subproject)
        debugstl = self.get_compileropt_value('debugstl', target, subproject)
        eh = self.get_compileropt_value('eh', target, subproject)

        assert isinstance(rtti, bool)
        assert isinstance(eh, str)
        assert isinstance(debugstl, bool)

        non_msvc_eh_options(eh, args)

        if not rtti:
            args.append('-fno-rtti')

        # We may want to handle libc++'s debugstl mode here too
        if debugstl:
            args.append('-D_GLIBCXX_DEBUG=1')
        return args

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append(self._find_best_cpp_std(std))
        return args

    def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        if self.info.is_windows() or self.info.is_cygwin():
            # without a typedict mypy can't understand this.
            retval = self.get_compileropt_value('winlibs', target, subproject)
            assert isinstance(retval, list)
            libs: T.List[str] = retval[:]
            for l in libs:
                assert isinstance(l, str)
            return libs
        return []

    def get_assert_args(self, disable: bool) -> T.List[str]:
        if disable:
            return ['-DNDEBUG']

        # Don't inject the macro if the compiler already has it pre-defined.
        for macro in ['_GLIBCXX_ASSERTIONS', '_LIBCPP_HARDENING_MODE', '_LIBCPP_ENABLE_ASSERTIONS']:
            if self.defines.get(macro) is not None:
                return []

        # For GCC, we can assume that the libstdc++ version is the same as
        # the compiler itself. Anything else isn't supported.
        if self.language_stdlib_provider == 'stdc++':
            return ['-D_GLIBCXX_ASSERTIONS=1']
        else:
            # One can use -stdlib=libc++ with GCC, it just (as of 2025) requires
            # an experimental configure arg to expose that. libc++ supports "multiple"
            # versions of GCC (only ever one version of GCC per libc++ version), but
            # that is "multiple" for our purposes as we can't assume a mapping.
            if version_compare(self.version, '>=18'):
                return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST']

        return []

    def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
        return ['-fpch-preprocess', '-include', os.path.basename(header)]

    def get_cpp_modules_args(self) -> T.List[str]:
        return ['-fmodules', '-fmodules-ts']


class PGICPPCompiler(PGICompiler, CPPCompiler):
    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        PGICompiler.__init__(self)


class NvidiaHPC_CPPCompiler(PGICompiler, CPPCompiler):

    id = 'nvidia_hpc'

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        PGICompiler.__init__(self)

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()
        cppstd_choices = [
            'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++20', 'c++23',
            'gnu++98', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++20'
        ]
        std_opt = opts[self.form_compileropt_key('std')]
        assert isinstance(std_opt, options.UserStdOption), 'for mypy'
        std_opt.set_versions(cppstd_choices)
        return opts

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append(self._find_best_cpp_std(std))
        return args


class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler):
    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 defines: T.Optional[T.Dict[str, str]] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        ElbrusCompiler.__init__(self)

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()

        key = self.form_compileropt_key('eh')
        opts[key] = options.UserComboOption(
            self.make_option_name(key),
            'C++ exception handling type.',
            'default',
            choices=['none', 'default', 'a', 's', 'sc'])

        key = self.form_compileropt_key('debugstl')
        opts[key] = options.UserBooleanOption(
            self.make_option_name(key),
            'STL debug mode',
            False)

        cpp_stds = ['c++98']
        if version_compare(self.version, '>=1.20.00'):
            cpp_stds += ['c++03', 'c++0x', 'c++11']
        if version_compare(self.version, '>=1.21.00') and version_compare(self.version, '<1.22.00'):
            cpp_stds += ['c++14', 'c++1y']
        if version_compare(self.version, '>=1.22.00'):
            cpp_stds += ['c++14']
        if version_compare(self.version, '>=1.23.00'):
            cpp_stds += ['c++1y']
        if version_compare(self.version, '>=1.24.00'):
            cpp_stds += ['c++1z', 'c++17']
        if version_compare(self.version, '>=1.25.00'):
            cpp_stds += ['c++2a']
        if version_compare(self.version, '>=1.26.00'):
            cpp_stds += ['c++20']
        if version_compare(self.version, '>=1.28.00'):
            cpp_stds += ['c++2b', 'c++23']

        key = self.form_compileropt_key('std')
        std_opt = opts[key]
        assert isinstance(std_opt, options.UserStdOption), 'for mypy'
        std_opt.set_versions(cpp_stds, gnu=True)
        return opts

    # Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error.
    # So we should explicitly fail at this case.
    def has_function(self, funcname: str, prefix: str, *,
                     extra_args: T.Optional[T.List[str]] = None,
                     dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]:
        if funcname == 'lchmod':
            return False, False
        return super().has_function(funcname, prefix, extra_args=extra_args, dependencies=dependencies)

    # Elbrus C++ compiler does not support RTTI, so don't check for it.
    def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        eh = self.get_compileropt_value('eh', target, subproject)
        assert isinstance(eh, str)

        non_msvc_eh_options(eh, args)

        debugstl = self.get_compileropt_value('debugstl', target, subproject)
        assert isinstance(debugstl, bool)
        if debugstl:
            args.append('-D_GLIBCXX_DEBUG=1')
        return args

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append(self._find_best_cpp_std(std))
        return args


class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        IntelGnuLikeCompiler.__init__(self)
        self.lang_header = 'c++-header'
        default_warn_args = ['-Wall', '-w3', '-Wpch-messages']
        self.warn_args = {'0': [],
                          '1': default_warn_args + ['-diag-disable:remark'],
                          '2': default_warn_args + ['-Wextra', '-diag-disable:remark'],
                          '3': default_warn_args + ['-Wextra', '-diag-disable:remark'],
                          'everything': default_warn_args + ['-Wextra']}

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()

        key = self.form_compileropt_key('eh')
        opts[key] = options.UserComboOption(
            self.make_option_name(key),
            'C++ exception handling type.',
            'default',
            choices=['none', 'default', 'a', 's', 'sc'])

        key = self.form_compileropt_key('rtti')
        opts[key] = options.UserBooleanOption(
            self.make_option_name(key),
            'Enable RTTI',
            True)

        key = self.form_compileropt_key('debugstl')
        opts[key] = options.UserBooleanOption(
            self.make_option_name(key),
            'STL debug mode',
            False)

        # Every Unix compiler under the sun seems to accept -std=c++03,
        # with the exception of ICC. Instead of preventing the user from
        # globally requesting C++03, we transparently remap it to C++98
        c_stds = ['c++98', 'c++03']
        g_stds = ['gnu++98', 'gnu++03']
        if version_compare(self.version, '>=15.0.0'):
            c_stds += ['c++11', 'c++14']
            g_stds += ['gnu++11']
        if version_compare(self.version, '>=16.0.0'):
            c_stds += ['c++17']
        if version_compare(self.version, '>=17.0.0'):
            g_stds += ['gnu++14']
        if version_compare(self.version, '>=19.1.0'):
            c_stds += ['c++2a']
            g_stds += ['gnu++2a']

        self._update_language_stds(opts, c_stds + g_stds)
        return opts

    def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []

        rtti = self.get_compileropt_value('rtti', target, subproject)
        debugstl = self.get_compileropt_value('debugstl', target, subproject)
        eh = self.get_compileropt_value('eh', target, subproject)

        assert isinstance(rtti, bool)
        assert isinstance(eh, str)
        assert isinstance(debugstl, bool)

        if eh == 'none':
            args.append('-fno-exceptions')
        if not rtti:
            args.append('-fno-rtti')
        if debugstl:
            args.append('-D_GLIBCXX_DEBUG=1')
        return args

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            remap_cpp03 = {
                'c++03': 'c++98',
                'gnu++03': 'gnu++98'
            }
            args.append('-std=' + remap_cpp03.get(std, std))

        return args

    def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        return []


class IntelLLVMCPPCompiler(IntelLLVMLikeCompiler, ClangCPPCompiler):

    id = 'intel-llvm'


class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):

    """Mixin for C++ specific method overrides in MSVC-like compilers."""

    VC_VERSION_MAP = {
        'none': (True, None),
        'vc++11': (True, 11),
        'vc++14': (True, 14),
        'vc++17': (True, 17),
        'vc++20': (True, 20),
        'vc++latest': (True, "latest"),
        'c++11': (False, 11),
        'c++14': (False, 14),
        'c++17': (False, 17),
        'c++20': (False, 20),
        'c++latest': (False, "latest"),
    }

    def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        # need a typeddict for this
        key = self.form_compileropt_key('winlibs').evolve(subproject=subproject)
        if target:
            value = self.environment.coredata.get_option_for_target(target, key)
        else:
            value = self.environment.coredata.optstore.get_value_for(key)
        return T.cast('T.List[str]', value)[:]

    def _get_options_impl(self, opts: 'MutableKeyedOptionDictType', cpp_stds: T.List[str]) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()

        key = self.form_compileropt_key('eh')
        opts[key] = options.UserComboOption(
            self.make_option_name(key),
            'C++ exception handling type.',
            'default',
            choices=['none', 'default', 'a', 's', 'sc'])

        key = self.form_compileropt_key('rtti')
        opts[key] = options.UserBooleanOption(
            self.make_option_name(key),
            'Enable RTTI',
            True)

        key = self.form_compileropt_key('winlibs')
        opts[key] = options.UserStringArrayOption(
            self.make_option_name(key),
            'Standard Win libraries to link against',
            msvc_winlibs)

        std_opt = opts[self.form_compileropt_key('std')]
        assert isinstance(std_opt, options.UserStdOption), 'for mypy'
        std_opt.set_versions(cpp_stds)

        if version_compare(self.version, '>=19.44.35219'):
            key = self.form_compileropt_key('importstd')
            opts[key] = options.UserComboOption(self.make_option_name(key),
                                                'Use #import std.',
                                                'false',
                                                choices=['false', 'true'])
        return opts

    def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []

        eh = self.get_compileropt_value('eh', target, subproject)
        rtti = self.get_compileropt_value('rtti', target, subproject)

        assert isinstance(rtti, bool)
        assert isinstance(eh, str)

        if eh == 'default':
            args.append('/EHsc')
        elif eh == 'none':
            args.append('/EHs-c-')
        else:
            args.append('/EH' + eh)

        if not rtti:
            args.append('/GR-')

        return args

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)

        permissive, ver = self.VC_VERSION_MAP[std]
        if ver is not None:
            args.append(f'/std:c++{ver}')
        if not permissive:
            args.append('/permissive-')
        return args

    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
        # XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class.
        return Compiler.get_compiler_check_args(self, mode)

class CPP11AsCPP14Mixin(CompilerMixinBase):

    """Mixin class for VisualStudio and ClangCl to replace C++11 std with C++14.

    This is a limitation of Clang and MSVC that ICL doesn't share.
    """

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        # Note: there is no explicit flag for supporting C++11; we attempt to do the best we can
        # which means setting the C++ standard version to C++14, in compilers that support it
        # (i.e., after VS2015U3)
        # if one is using anything before that point, one cannot set the standard.
        stdkey = self.form_compileropt_key('std').evolve(subproject=subproject)
        if target is not None:
            std = self.environment.coredata.get_option_for_target(target, stdkey)
        else:
            std = self.environment.coredata.optstore.get_value_for(stdkey)
        if std in {'vc++11', 'c++11'}:
            mlog.warning(self.id, 'does not support C++11;',
                         'attempting best effort; setting the standard to C++14',
                         once=True, fatal=False)
        original_args = super().get_option_std_args(target, subproject)
        std_mapping = {'/std:c++11': '/std:c++14'}
        processed_args = [std_mapping.get(x, x) for x in original_args]
        return processed_args


class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, MSVCCompiler, CPPCompiler):

    id = 'msvc'

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, target: str,
                 linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        MSVCCompiler.__init__(self, target)

        # By default, MSVC has a broken __cplusplus define that pretends to be c++98:
        # https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=msvc-160
        # Pass the flag to enable a truthful define, if possible.
        if version_compare(self.version, '>= 19.14.26428'):
            self.always_args = self.always_args + ['/Zc:__cplusplus']

    def get_options(self) -> 'MutableKeyedOptionDictType':
        cpp_stds = ['none', 'c++11', 'vc++11']
        # Visual Studio 2015 and later
        if version_compare(self.version, '>=19'):
            cpp_stds.extend(['c++14', 'c++latest', 'vc++latest'])
        # Visual Studio 2017 and later
        if version_compare(self.version, '>=19.11'):
            cpp_stds.extend(['vc++14', 'c++17', 'vc++17'])
        if version_compare(self.version, '>=19.29'):
            cpp_stds.extend(['c++20', 'vc++20'])
        return self._get_options_impl(super().get_options(), cpp_stds)

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        std = self.get_compileropt_value('std', target, subproject)
        if std != 'none' and version_compare(self.version, '<19.00.24210'):
            mlog.warning('This version of MSVC does not support cpp_std arguments', fatal=False)

        args = super().get_option_std_args(target, subproject)

        if version_compare(self.version, '<19.11'):
            try:
                i = args.index('/permissive-')
            except ValueError:
                return args
            del args[i]
        return args

    def get_cpp_modules_args(self) -> T.List[str]:
        return ['/interface']

class ClangClCPPCompiler(VisualStudioLikeCPPCompilerMixin, ClangClCompiler, CPPCompiler):

    id = 'clang-cl'

    def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, target: str,
                 linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, [], exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        ClangClCompiler.__init__(self, target)

    def get_options(self) -> 'MutableKeyedOptionDictType':
        cpp_stds = list(self.VC_VERSION_MAP) + ['c++23', 'vc++23']
        return self._get_options_impl(super().get_options(), cpp_stds)

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std == 'none':
            return []
        # c++latest and vc++latest have no /clang:-std= equivalent
        if std in {'c++latest', 'vc++latest'}:
            args = ['/std:c++latest']
            if std == 'c++latest':
                args.append('/permissive-')
            return args
        # vc++ variants: permissive mode, strip 'vc++' prefix to get clang std name
        if std.startswith('vc++'):
            return [f'/clang:-std=c++{std[4:]}']
        # c++ variants: strict conformance mode
        return [f'/clang:-std={std}', '/permissive-']

    def get_cpp_modules_args(self) -> T.List[str]:
        # clang-cl does not support /interface.
        return ['-fmodules', '-fmodules-ts']


class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLikeCompiler, CPPCompiler):

    def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, target: str,
                 linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, [], exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        IntelVisualStudioLikeCompiler.__init__(self, target)

    def get_options(self) -> 'MutableKeyedOptionDictType':
        # This has only been tested with version 19.0, 2021.2.1, 2024.4.2 and 2025.0.1
        if version_compare(self.version, '<2021.1.0'):
            cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest']
        else:
            cpp_stds = ['none', 'c++14', 'c++17', 'c++latest']
        if version_compare(self.version, '>=2024.1.0'):
            cpp_stds += ['c++20']
        return self._get_options_impl(super().get_options(), cpp_stds)

    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
        # XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class.
        return IntelVisualStudioLikeCompiler.get_compiler_check_args(self, mode)


class IntelLLVMClCPPCompiler(IntelClCPPCompiler):

    id = 'intel-llvm-cl'


class ArmCPPCompiler(ArmCompiler, CPPCompiler):
    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        ArmCompiler.__init__(self)

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()
        std_opt = self.form_compileropt_key('std')
        assert isinstance(std_opt, options.UserStdOption), 'for mypy'
        std_opt.set_versions(['c++03', 'c++11'])
        return opts

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std == 'c++11':
            args.append('--cpp11')
        elif std == 'c++03':
            args.append('--cpp')
        return args

    def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        return []

    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
        return []


class CcrxCPPCompiler(CcrxCompiler, CPPCompiler):
    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        CcrxCompiler.__init__(self)

    # Override CCompiler.get_always_args
    def get_always_args(self) -> T.List[str]:
        return ['-nologo', '-lang=cpp']

    def get_compile_only_args(self) -> T.List[str]:
        return []

    def get_output_args(self, outputname: str) -> T.List[str]:
        return [f'-output=obj={outputname}']

    def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        return []

    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
        return []

class TICPPCompiler(TICompiler, CPPCompiler):
    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        TICompiler.__init__(self)

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()
        key = self.form_compileropt_key('std')
        std_opt = opts[key]
        assert isinstance(std_opt, options.UserStdOption), 'for mypy'
        std_opt.set_versions(['c++03'])
        return opts

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append('--' + std)
        return args

    def get_always_args(self) -> T.List[str]:
        return []

    def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]:
        return []

class C2000CPPCompiler(TICPPCompiler):
    # Required for backwards compat with projects created before ti-cgt support existed
    id = 'c2000'

class C6000CPPCompiler(TICPPCompiler):
    id = 'c6000'

class MetrowerksCPPCompilerARM(MetrowerksCompiler, CPPCompiler):
    id = 'mwccarm'

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        MetrowerksCompiler.__init__(self)

    def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]:
        return mwccarm_instruction_set_args.get(instruction_set, None)

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()
        self._update_language_stds(opts, [])
        return opts

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append('-lang')
            args.append(std)
        return args

class MetrowerksCPPCompilerEmbeddedPowerPC(MetrowerksCompiler, CPPCompiler):
    id = 'mwcceppc'

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional['DynamicLinker'] = None,
                 full_version: T.Optional[str] = None):
        CPPCompiler.__init__(self, ccache, exelist, version, for_machine,
                             env, linker=linker, full_version=full_version)
        MetrowerksCompiler.__init__(self)

    def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]:
        return mwcceppc_instruction_set_args.get(instruction_set, None)

    def get_options(self) -> 'MutableKeyedOptionDictType':
        opts = super().get_options()
        self._update_language_stds(opts, [])
        return opts

    def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
        args: T.List[str] = []
        std = self.get_compileropt_value('std', target, subproject)
        assert isinstance(std, str)
        if std != 'none':
            args.append('-lang ' + std)
        return args


class Xc32CPPCompiler(Xc32CPPStds, Xc32Compiler, GnuCPPCompiler):

    """Microchip XC32 C++ compiler."""

    def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
                 env: Environment, linker: T.Optional[DynamicLinker] = None,
                 defines: T.Optional[T.Dict[str, str]] = None,
                 full_version: T.Optional[str] = None):
        GnuCPPCompiler.__init__(self, ccache, exelist, version, for_machine, env,
                                linker=linker, full_version=full_version, defines=defines)
        Xc32Compiler.__init__(self)
