# Copyright © 2017-2018 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

project('gcc func attributes', ['c', 'cpp'])

# For msvc these will fail because msvc doesn't support __attribute__, for
# Clang and GCC, they should pass.
c = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')

if c.get_id() == 'pgi'
  error('MESON_SKIP_TEST: PGI supports its own set of features, will need a separate list for PGI to test it.')
endif

expected = {}
expected_default = not ['msvc', 'clang-cl', 'intel-cl'].contains(c.get_id())

# Q: Why is ifunc not in this list or any of the below lists?
# A: It's too damn hard to figure out if you actually support it, since it
#    requires both compiler and libc support, and there isn't a good way to
#    figure that out except by running the code we're trying to test.
attributes = [
  'aligned',
  'always_inline',
  'cold',
  'const',
  'constructor',
  'constructor_priority',
  'deprecated',
  'destructor',
  'flatten',
  'format',
  'format_arg',
  'gnu_inline',
  'hot',
  'malloc',
  'noinline',
  'nonnull',
  'noreturn',
  'nothrow',
  'pure',
  'section',
  'sentinel',
  'unused',
  'used',
  'vector_size',
  'warn_unused_result',
  'weak',
  'dllexport',
  'dllimport',
]

expected += {
  'dllexport': ['windows', 'cygwin'].contains(host_machine.system()),
  'dllimport': ['windows', 'cygwin'].contains(host_machine.system()),
}

if c.get_id() == 'gcc' and ['windows', 'cygwin'].contains(host_machine.system())
  expected += {
    'visibility': false,
    'visibility:hidden': false,
    'visibility:internal': false,
    'visibility:protected': false,
  }
endif

if c.get_id() != 'intel'
  # not supported by icc as of 19.0.0
  attributes += 'weakref'
endif

# These are unsupported on darwin with apple clang 9.1.0
if host_machine.system() != 'darwin'
  attributes += 'alias'
  attributes += 'visibility'
  attributes += 'visibility:default'
  attributes += 'visibility:hidden'
  attributes += 'visibility:internal'
  attributes += 'visibility:protected'
  attributes += 'alloc_size'
endif

# gcc doesn't support constructor_priority on darwin
if c.get_id() == 'gcc' and host_machine.system() == 'darwin'
  expected += {'constructor_priority': false}
endif

if ['gcc', 'intel'].contains(c.get_id())
  # not supported by clang as of 5.0.0 (at least up to 6.0.1)
  attributes += 'artificial'
  attributes += 'error'
  attributes += 'externally_visible'
  attributes += 'leaf'
  attributes += 'noclone'
  attributes += 'optimize'
  attributes += 'warning'

  if c.get_id() == 'gcc' and c.version().version_compare('>= 7.0.0')
    attributes += 'fallthrough'
  endif

  # XXX(arsen): limited to clang 13+ even though gcc 11 has it, since gcc
  # detects support for it at compile time based on binutils version
  if c.get_id() == 'clang' and c.version().version_compare('>= 13.0.0')
    attributes += 'retain'
  endif
endif

if c.get_id() == 'clang'
  if c.version().version_compare('>= 18.0.0')
    attributes += 'counted_by'
  endif
endif

if c.get_id() == 'gcc'
  if c.version().version_compare('>= 15.1')
    attributes += 'counted_by'
  endif
  if c.version().version_compare('>= 14.1')
    attributes += 'null_terminated_string_arg'
  endif
endif

if get_option('mode') == 'single'
  foreach a : attributes
    x = c.has_function_attribute(a)
    expected_result = expected.get(a, expected_default)
    assert(x == expected_result, '@0@: @1@'.format(c.get_id(), a))
    # counted_by is not currently supported by GCC or clang on C++
    if a != 'counted_by'
      x = cpp.has_function_attribute(a)
      assert(x == expected_result, '@0@: @1@'.format(cpp.get_id(), a))
    endif
  endforeach
else
  multi_expected_c = []
  multi_expected_cpp = []
  foreach a : attributes
    if expected.get(a, expected_default)
      multi_expected_c += a
      # counted_by is not currently supported by GCC or clang on C++
      if a != 'counted_by'
        multi_expected_cpp += a
      endif
    endif
  endforeach

  multi_check = c.get_supported_function_attributes(attributes)
  assert(multi_check == multi_expected_c, 'get_supported_function_arguments works (C)')
  multi_check = cpp.get_supported_function_attributes(attributes)
  assert(multi_check == multi_expected_cpp, 'get_supported_function_arguments works (C++)')
endif
