#!/usr/bin/python3
# Generate tests for <tgmath.h> macros.
# Copyright (C) 2017-2025 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
#
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <https://www.gnu.org/licenses/>.
# As glibc does not support decimal floating point, the types to
# consider for generic parameters are standard and binary
# floating-point types, and integer types which are treated as
# _Float32x if any argument has a _FloatNx type and otherwise as
# double. The corresponding complex types may also be used (including
# complex integer types, which are a GNU extension, but are currently
# disabled here because they do not work properly with tgmath.h).
# C23 makes the <tgmath.h> rules for selecting a function to call
# correspond to the usual arithmetic conversions (applied successively
# to the arguments for generic parameters in order), which choose the
# type whose set of values contains that of the other type (undefined
# behavior if neither type's set of values is a superset of the
# other), with interchange types being preferred to standard types
# (long double, double, float), being preferred to extended types
# (_Float128x, _Float64x, _Float32x).
# For the standard and binary floating-point types supported by GCC 7
# on any platform, this means the resulting type is the last of the
# given types in one of the following orders, or undefined behavior if
# types with both ibm128 and binary128 representation are specified.
# If double = long double: _Float16, float, _Float32, _Float32x,
# double, long double, _Float64, _Float64x, _Float128.
# Otherwise: _Float16, float, _Float32, _Float32x, double, _Float64,
# _Float64x, long double, _Float128.
# We generate tests to verify the return type is exactly as expected.
# We also verify that the function called is real or complex as
# expected, and that it is called for the right floating-point format
# (but it is OK to call a double function instead of a long double one
# if they have the same format, for example). For all the formats
# supported on any given configuration of glibc, the MANT_DIG value
# uniquely determines the format.
import string
import sys
class Type(object):
"""A type that may be used as an argument for generic parameters."""
# All possible argument or result types.
all_types_list = []
# All argument types.
argument_types_list = []
# All real argument types.
real_argument_types_list = []
# Real argument types that correspond to a standard floating type
# (float, double or long double; not _FloatN or _FloatNx).
standard_real_argument_types_list = []
# The real floating types by their order properties (which are
# tuples giving the positions in both the possible orders above).
real_types_order = {}
# The type double.
double_type = None
# The type long double.
long_double_type = None
# The type _Complex double.
complex_double_type = None
# The type _Float64.
float64_type = None
# The type _Complex _Float64.
complex_float64_type = None
# The type _Float32x.
float32x_type = None
# The type _Complex _Float32x.
complex_float32x_type = None
# The type _Float64x.
float64x_type = None
def __init__(self, name, suffix=None, mant_dig=None, condition='1',
order=None, integer=False, complex=False, real_type=None,
floatnx=False):
"""Initialize a Type object, creating any corresponding complex type
in the process."""
self.name = name
self.suffix = suffix
self.mant_dig = mant_dig