# SPDX-License-Identifier: Apache-2.0
# Copyright 2019-2022 The meson development team

from __future__ import annotations

"""Abstractions for the LLVM/Clang compiler family."""

import os
import shutil
import typing as T

from ... import mesonlib
from ... import options
from ...linkers.linkers import AppleDynamicLinker, ClangClDynamicLinker, LLVMDynamicLinker, GnuGoldDynamicLinker, \
    MoldDynamicLinker, MSVCDynamicLinker
from ...options import OptionKey
from ..compilers import CompileCheckMode
from .gnu import GnuLikeCompiler

if T.TYPE_CHECKING:
    from ...coredata import MutableKeyedOptionDictType
    from ...environment import Environment
    from ...dependencies import Dependency  # noqa: F401
    from ..compilers import Compiler

    CompilerMixinBase = Compiler
else:
    CompilerMixinBase = object

clang_color_args: T.Dict[str, T.List[str]] = {
    'auto': ['-fdiagnostics-color=auto'],
    'always': ['-fdiagnostics-color=always'],
    'never': ['-fdiagnostics-color=never'],
}

clang_optimization_args: T.Dict[str, T.List[str]] = {
    'plain': [],
    '0': ['-O0'],
    'g': ['-Og'],
    '1': ['-O1'],
    '2': ['-O2'],
    '3': ['-O3'],
    's': ['-Oz'],
}

clang_lang_map = {
    'c': 'c',
    'cpp': 'c++',
    'objc': 'objective-c',
    'objcpp': 'objective-c++',
}

class ClangCompiler(GnuLikeCompiler):

    id = 'clang'

    def __init__(self, defines: T.Optional[T.Dict[str, str]]):
        super().__init__()
        self.defines = defines or {}
        self.base_options.update(
            {OptionKey('b_colorout'), OptionKey('b_lto_threads'), OptionKey('b_lto_mode'), OptionKey('b_thinlto_cache'),
             OptionKey('b_thinlto_cache_dir')})

        # TODO: this really should be part of the linker base_options, but
        # linkers don't have base_options.
        if isinstance(self.linker, AppleDynamicLinker):
            self.base_options.add(OptionKey('b_bitcode'))
        elif isinstance(self.linker, MSVCDynamicLinker):
            self.base_options.add(OptionKey('b_vscrt'))
        # All Clang backends can also do LLVM IR
        self.can_compile_suffixes.add('ll')

    def get_colorout_args(self, colortype: str) -> T.List[str]:
        return clang_color_args[colortype][:]

    def has_builtin_define(self, define: str) -> bool:
        return define in self.defines

    def get_builtin_define(self, define: str) -> T.Optional[str]:
        return self.defines.get(define)

    def get_optimization_args(self, optimization_level: str) -> T.List[str]:
        return clang_optimization_args[optimization_level]

    def get_pch_suffix(self) -> str:
        return 'pch'

    def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
        # Workaround for Clang bug http://llvm.org/bugs/show_bug.cgi?id=15136
        # This flag is internal to Clang (or at least not documented on the man page)
        # so it might change semantics at any time.
        return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))]

    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
        # Clang is different than GCC, it will return True when a symbol isn't
        # defined in a header. Specifically this is caused by a functionality
        # both GCC and clang have: for some "well known" functions, arbitrarily
        # chosen, they provide fixit suggestions for the header you should try
        # including.
        #
        # - With GCC, this is a note appended to the prexisting diagnostic
        #   "error: undeclared identifier"
        #
        # - With clang, the error is converted to a c89'ish implicit function
        #   declaration instead, which can be disabled with -Wno-error and on
        #   clang < 16, simply passes compilation by default.
        #
        # One example of a clang fixit suggestion is for `strlcat`, which
        # triggers this.
        #
        # This was reported in 2017 and promptly fixed. Just kidding!
        # https://github.com/llvm/llvm-project/issues/33905
        myargs: T.List[str] = ['-Werror=implicit-function-declaration']
        if mode is CompileCheckMode.COMPILE:
            myargs.extend(['-Werror=unknown-warning-option', '-Werror=unused-command-line-argument'])
            if mesonlib.version_compare(self.version, '>=3.6.0'):
                myargs.append('-Werror=ignored-optimization-argument')
        return super().get_compiler_check_args(mode) + myargs

    def has_function(self, funcname: str, prefix: str, env: 'Environment', *,
                     extra_args: T.Optional[T.List[str]] = None,
                     dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]:
        if extra_args is None:
            extra_args = []
        # Starting with XCode 8, we need to pass this to force linker
        # visibility to obey OS X/iOS/tvOS minimum version targets with
        # -mmacosx-version-min, -miphoneos-version-min, -mtvos-version-min etc.
        # https://github.com/Homebrew/homebrew-core/issues/3727
        # TODO: this really should be communicated by the linker
        if isinstance(self.linker, AppleDynamicLinker) and mesonlib.version_compare(self.version, '>=8.0'):
            extra_args.append('-Wl,-no_weak_imports')
        return super().has_function(funcname, prefix, env, extra_args=extra_args,
                                    dependencies=dependencies)

    def openmp_flags(self, env: Environment) -> T.List[str]:
        if mesonlib.version_compare(self.version, '>=3.8.0'):
            return ['-fopenmp']
        elif mesonlib.version_compare(self.version, '>=3.7.0'):
            return ['-fopenmp=libomp']
        else:
            # Shouldn't work, but it'll be checked explicitly in the OpenMP dependency.
            return []

    def gen_vs_module_defs_args(self, defsfile: str) -> T.List[str]:
        if isinstance(self.linker, (ClangClDynamicLinker, MSVCDynamicLinker)):
            # With MSVC, DLLs only export symbols that are explicitly exported,
            # so if a module defs file is specified, we use that to export symbols
            return ['-Wl,/DEF:' + defsfile]
        return super().gen_vs_module_defs_args(defsfile)

    @classmethod
    def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
        # Clang additionally can use a linker specified as a path, which GCC
        # (and other gcc-like compilers) cannot. This is because clang (being
        # llvm based) is retargetable, while GCC is not.
        #

        # qcld: Qualcomm Snapdragon linker, based on LLVM
        if linker == 'qcld':
            return ['-fuse-ld=qcld']
        if linker == 'mold':
            return ['-fuse-ld=mold']

        if shutil.which(linker):
            if not shutil.which(linker):
                raise mesonlib.MesonException(
                    f'Cannot find linker {linker}.')
            return [f'-fuse-ld={linker}']
        return super().use_linker_args(linker, version)

    def get_has_func_attribute_extra_args(self, name: str) -> T.List[str]:
        # Clang only warns about unknown or ignored attributes, so force an
        # error.
        return ['-Werror=attributes']

    def get_coverage_link_args(self) -> T.List[str]:
        return ['--coverage']

    def get_lto_compile_args(self, *, threads: int = 0, mode: str = 'default') -> T.List[str]:
        args: T.List[str] = []
        if mode == 'thin':
            # ThinLTO requires the use of gold, lld, ld64, lld-link or mold 1.1+
            if isinstance(self.linker, (MoldDynamicLinker)):
                # https://github.com/rui314/mold/commit/46995bcfc3e3113133620bf16445c5f13cd76a18
                if not mesonlib.version_compare(self.linker.version, '>=1.1'):
                    raise mesonlib.MesonException("LLVM's ThinLTO requires mold 1.1+")
            elif not isinstance(self.linker, (AppleDynamicLinker, ClangClDynamicLinker, LLVMDynamicLinker, GnuGoldDynamicLinker)):
                raise mesonlib.MesonException(f"LLVM's ThinLTO only works with gold, lld, lld-link, ld64 or mold, not {self.linker.id}")
            args.append(f'-flto={mode}')
        else:
            assert mode == 'default', 'someone forgot to wire something up'
            args.extend(super().get_lto_compile_args(threads=threads))
        return args

    def linker_to_compiler_args(self, args: T.List[str]) -> T.List[str]:
        if isinstance(self.linker, (ClangClDynamicLinker, MSVCDynamicLinker)):
            return [flag if flag.startswith('-Wl,') or flag.startswith('-fuse-ld=') else f'-Wl,{flag}' for flag in args]
        else:
            return args

    def get_lto_link_args(self, *, threads: int = 0, mode: str = 'default',
                          thinlto_cache_dir: T.Optional[str] = None) -> T.List[str]:
        args = self.get_lto_compile_args(threads=threads, mode=mode)
        if mode == 'thin' and thinlto_cache_dir is not None:
            # We check for ThinLTO linker support above in get_lto_compile_args, and all of them support
            # get_thinlto_cache_args as well
            args.extend(self.linker.get_thinlto_cache_args(thinlto_cache_dir))
        # In clang -flto-jobs=0 means auto, and is the default if unspecified, just like in meson
        if threads > 0:
            if not mesonlib.version_compare(self.version, '>=4.0.0'):
                raise mesonlib.MesonException('clang support for LTO threads requires clang >=4.0')
            args.append(f'-flto-jobs={threads}')
        return args


class ClangCStds(CompilerMixinBase):

    """Mixin class for clang based compilers for setting C standards.

    This is used by both ClangCCompiler and ClangClCompiler, as they share
    the same versions
    """

    _C17_VERSION = '>=6.0.0'
    _C18_VERSION = '>=8.0.0'
    _C2X_VERSION = '>=9.0.0'
    _C23_VERSION = '>=18.0.0'
    _C2Y_VERSION = '>=19.0.0'

    def get_options(self) -> MutableKeyedOptionDictType:
        opts = super().get_options()
        stds = ['c89', 'c99', 'c11']
        # https://releases.llvm.org/6.0.0/tools/clang/docs/ReleaseNotes.html
        # https://en.wikipedia.org/wiki/Xcode#Latest_versions
        if mesonlib.version_compare(self.version, self._C17_VERSION):
            stds += ['c17']
        if mesonlib.version_compare(self.version, self._C18_VERSION):
            stds += ['c18']
        if mesonlib.version_compare(self.version, self._C2X_VERSION):
            stds += ['c2x']
        if mesonlib.version_compare(self.version, self._C23_VERSION):
            stds += ['c23']
        if mesonlib.version_compare(self.version, self._C2Y_VERSION):
            stds += ['c2y']
        key = self.form_compileropt_key('std')
        std_opt = opts[key]
        assert isinstance(std_opt, options.UserStdOption), 'for mypy'
        std_opt.set_versions(stds, gnu=True)
        return opts


class ClangCPPStds(CompilerMixinBase):

    """Mixin class for clang based compilers for setting C++ standards.

    This is used by the ClangCPPCompiler
    """

    _CPP23_VERSION = '>=12.0.0'
    _CPP26_VERSION = '>=17.0.0'

    def get_options(self) -> MutableKeyedOptionDictType:
        opts = super().get_options()
        stds = [
            'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a',
            'c++20',
        ]
        if mesonlib.version_compare(self.version, self._CPP23_VERSION):
            stds.append('c++23')
        if mesonlib.version_compare(self.version, self._CPP26_VERSION):
            stds.append('c++26')
        key = self.form_compileropt_key('std')
        std_opt = opts[key]
        assert isinstance(std_opt, options.UserStdOption), 'for mypy'
        std_opt.set_versions(stds, gnu=True)
        return opts
