# Copyright 2020-2022 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later

# General code to enable approximately all warnings in GCC 12, clang, and MSVC.
#
# This is trivial for clang and MSVC, but GCC doesn't have an "everything"
# option, so we need to enable everything we want explicitly.  Wall is assumed,
# but Wextra is not, for stability.
#
# These are collected from common.opt and c.opt in the GCC source, and manually
# curated with the help of the GCC documentation.  Warnings that are
# application-specific, historical, or about compatibility between specific
# language revisions are omitted.  The intent here is to have roughly the same
# meaning as clang's Weverything: extremely strict, but general.  Specifically
# omitted are:
#
# General:
#
# Wabi=
# Waggregate-return
# Walloc-size-larger-than=BYTES
# Walloca-larger-than=BYTES
# Wframe-larger-than=BYTES
# Wlarger-than=BYTES
# Wstack-usage=BYTES
# Wsystem-headers
# Wtraditional
# Wtraditional-conversion
# Wtrampolines
# Wvla-larger-than=BYTES
#
# Build specific:
#
# Wpoison-system-directories
#
# C++ Specific:
#
# Wc++0x-compat
# Wc++1z-compat
# Wc++2a-compat
# Wctad-maybe-unsupported
# Wnamespaces
# Wtemplates

gcc_common_warnings = [
  '-Walloc-zero',
  '-Walloca',
  '-Wanalyzer-too-complex',
  '-Warith-conversion',
  '-Warray-bounds=2',
  '-Wattribute-alias=2',
  '-Wbidi-chars=ucn',
  '-Wcast-align=strict',
  '-Wcast-function-type',
  '-Wcast-qual',
  '-Wclobbered',
  '-Wconversion',
  '-Wdate-time',
  '-Wdisabled-optimization',
  '-Wdouble-promotion',
  '-Wduplicated-branches',
  '-Wduplicated-cond',
  '-Wempty-body',
  '-Wendif-labels',
  '-Wfloat-equal',
  '-Wformat-overflow=2',
  '-Wformat-signedness',
  '-Wformat-truncation=2',
  '-Wformat=2',
  '-Wignored-qualifiers',
  '-Wimplicit-fallthrough=3',
  '-Winit-self',
  '-Winline',
  '-Winvalid-pch',
  '-Wlogical-op',
  '-Wmissing-declarations',
  '-Wmissing-field-initializers',
  '-Wmissing-include-dirs',
  '-Wmultichar',
  '-Wnormalized=nfc',
  '-Wnull-dereference',
  '-Wopenacc-parallelism',
  '-Woverlength-strings',
  '-Wpacked',
  '-Wpacked-bitfield-compat',
  '-Wpadded',
  '-Wpointer-arith',
  '-Wredundant-decls',
  '-Wshadow',
  '-Wshift-negative-value',
  '-Wshift-overflow=2',
  '-Wstack-protector',
  '-Wstrict-aliasing=3',
  '-Wstrict-overflow=5',
  '-Wstring-compare',
  '-Wstringop-overflow=3',
  '-Wsuggest-attribute=cold',
  '-Wsuggest-attribute=const',
  '-Wsuggest-attribute=format',
  '-Wsuggest-attribute=malloc',
  '-Wsuggest-attribute=noreturn',
  '-Wsuggest-attribute=pure',
  '-Wswitch-default',
  '-Wswitch-enum',
  '-Wtrampolines',
  '-Wtrivial-auto-var-init',
  '-Wtype-limits',
  '-Wundef',
  '-Wuninitialized',
  '-Wunsafe-loop-optimizations',
  '-Wunused',
  '-Wunused-const-variable=2',
  '-Wunused-macros',
  '-Wvector-operation-performance',
  '-Wvla',
  '-Wwrite-strings',
]

#######
# C++ #
#######

if is_variable('cpp')
  all_cpp_warnings = []

  if cpp.get_id() == 'clang'
    all_cpp_warnings += [
      '-Weverything',
      '-Wno-c++98-compat',
      '-Wno-c++98-compat-pedantic'
    ]

    if not meson.is_cross_build()
      all_cpp_warnings += [
        '-Wno-poison-system-directories',
      ]
    endif

  elif cpp.get_id() == 'gcc'
    all_cpp_warnings += gcc_common_warnings + [
      '-Wabi-tag',
      '-Waligned-new=all',
      '-Wcatch-value=3',
      '-Wcomma-subscript',
      '-Wconditionally-supported',
      '-Wctor-dtor-privacy',
      '-Wdelete-non-virtual-dtor',
      '-Wdeprecated',
      '-Wdeprecated-copy',
      '-Wdeprecated-copy-dtor',
      '-Wdeprecated-enum-enum-conversion',
      '-Wdeprecated-enum-float-conversion',
      '-Weffc++',
      '-Wexpansion-to-defined',
      '-Wextra-semi',
      '-Wimport',
      '-Winvalid-imported-macros',
      '-Wmismatched-tags',
      '-Wmultiple-inheritance',
      '-Wnoexcept',
      '-Wnoexcept-type',
      '-Wnon-virtual-dtor',
      '-Wold-style-cast',
      '-Woverloaded-virtual',
      '-Wplacement-new=2',
      '-Wredundant-move',
      '-Wredundant-tags',
      '-Wregister',
      '-Wsign-compare',
      '-Wsign-promo',
      '-Wsized-deallocation',
      '-Wstrict-null-sentinel',
      '-Wsuggest-final-methods',
      '-Wsuggest-final-types',
      '-Wsuggest-override',
      '-Wuseless-cast',
      '-Wvirtual-inheritance',
      '-Wvolatile',
      '-Wzero-as-null-pointer-constant',
    ]

  elif cpp.get_id() == 'msvc'
    all_cpp_warnings += ['/Wall']
  endif

  all_cpp_warnings = cpp.get_supported_arguments(all_cpp_warnings)
  add_global_arguments(all_cpp_warnings, language: ['cpp'])
endif