From 78a7c3172fe2e6cd959abb8bfc69f6b0dc747d49 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Tue, 14 Oct 2014 15:44:36 -0400 Subject: [PATCH] machmode.h (int_n_data_t): New. * machmode.h (int_n_data_t): New. (int_n_enabled_p): New. (int_n_data): New. * tree.c (int_n_enabled_p): New. (int_n_trees): New. (make_or_reuse_type): Check for all __intN types, not just __int128. (build_common_tree_nodes): Likewise. Also fill in integer_typs[] entries. * tree.h (int128_integer_type_node): Remove. (int128_unsigned_type_node): Remove. (int_n_trees_t): New. (int_n_enabled_p): New. (int_n_trees): New. * toplev.c (standard_type_bitsize): New. (do_compile): Check which __intN types are enabled for the current run. * builtin-types.def (BT_INT128): Remove. (BT_UINT128): Remove. * machmode.def: Add macro to create __int128 for all targets. * stor-layout.c (mode_for_size): Support __intN types. (smallest_mode_for_size): Likewise. (initialize_sizetypes): Support __intN types. * genmodes.c (struct mode_data): Add int_n field. (blank_mode): Likewise. (INT_N): New. (make_int_n): New. (emit_insn_modes_h): Count __intN entries and define NUM_INT_N_ENTS. (emit_mode_int_n): New. (emit_insn_modes_c): Call it. * gimple.c (gimple_signed_or_unsigned_type): Check for all __intN types, not just __int128. * tree-core.h (integer_type_kind): Remove __int128-specific entries, reserve spots for __intN entries. libstdc++-v3/ * src/c++11/limits.cc: Add support for __intN types. * include/std/type_traits: Likewise. * include/std/limits: Likewise. * include/c_std/cstdlib: Likewise. * include/bits/cpp_type_traits.h: Likewise. * include/c_global/cstdlib: Likewise. c-family/ * c-pretty-print.c (pp_c_integer_constant): Check for all __intN types, not just __int128. * c-cppbuiltin.c (c_cpp_builtins): Add builtins for all __intN types, not just __int128. (cpp_atomic_builtins): Round pointer sizes up. (type_suffix): Use type precision, not specific types. * c-common.c (c_common_reswords): Remove __int128 special case. (c_common_type_for_size): Check for all __intN types, not just __int128. (c_common_type_for_mode): Likewise. (c_common_signed_or_unsigned_type): Likewise. (c_build_bitfield_integer_type): Likewise. (c_common_nodes_and_builtins): Likewise. (keyword_begins_type_specifier): Likewise. * c-common.h (rid): Remove RID_INT128 and add RID_INT_N_* for all __intN variants. c/ * c-parser.c (c_parse_init): Add RID entries for each __intN. (c_token_starts_typename): Check all __intN, not just __int128. (c_token_starts_declspecs): Likewise. (c_parser_declspecs): Likewise. (c_parser_attribute_any_word): Likewise. (c_parser_objc_selector): Likewise. * c-tree.h (c_typespec_keyword): cts_int128 -> cts_int_n. (struct c_declspecs): Add int_n_idx field to record *which* __intN is specified. * c-decl.c (declspecs_add_type): Check for all __intN, not just __int128. (finish_declspecs): Likewise. testsuite/ * g++.dg/abi/mangle64.C: New. cp/ * typeck.c (cp_common_type): Check for all __intN types, not just __int128. * decl.c (grokdeclarator): Likewise. * rtti.c (emit_support_tinfos): Check for all __intN types, not just __int128. * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): Check for all __intN types, not just __int128. (cp_parser_simple_type_specifier): Likewise. * mangle.c (integer_type_codes): Remove int128-specific codes. * cp-tree.h (cp_decl_specifier_seq): Add int_n_idx to store which __intN was specified. * lex.c (init_reswords): Reserve all __intN keywords. lto/ * lto-lang.c (lto_build_c_type_nodes): Check intN types for size-type as well. (lto_init): Initialize all intN types, not just int128. From-SVN: r216220 --- gcc/ChangeLog | 40 +++ gcc/builtin-types.def | 2 - gcc/c-family/ChangeLog | 19 ++ gcc/c-family/c-common.c | 82 +++-- gcc/c-family/c-common.h | 18 +- gcc/c-family/c-cppbuiltin.c | 37 ++- gcc/c-family/c-pretty-print.c | 16 +- gcc/c/ChangeLog | 15 + gcc/c/c-decl.c | 69 ++-- gcc/c/c-parser.c | 37 ++- gcc/c/c-tree.h | 4 +- gcc/cp/ChangeLog | 15 + gcc/cp/cp-tree.h | 6 +- gcc/cp/decl.c | 36 ++- gcc/cp/lex.c | 9 + gcc/cp/mangle.c | 5 +- gcc/cp/parser.c | 21 +- gcc/cp/rtti.c | 7 +- gcc/cp/typeck.c | 22 +- gcc/genmodes.c | 87 +++++- gcc/gimple.c | 26 +- gcc/lto/ChangeLog | 6 + gcc/lto/lto-lang.c | 32 +- gcc/machmode.def | 7 + gcc/machmode.h | 12 + gcc/stor-layout.c | 43 ++- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/g++.dg/abi/mangle64.C | 13 + gcc/toplev.c | 27 ++ gcc/tree-core.h | 12 +- gcc/tree.c | 60 +++- gcc/tree.h | 13 +- libstdc++-v3/ChangeLog | 9 + libstdc++-v3/include/bits/cpp_type_traits.h | 32 +- libstdc++-v3/include/c_global/cstdlib | 19 +- libstdc++-v3/include/c_std/cstdlib | 18 +- libstdc++-v3/include/std/limits | 329 +++++++++++--------- libstdc++-v3/include/std/type_traits | 77 ++++- libstdc++-v3/src/c++11/limits.cc | 108 ++++--- 39 files changed, 1041 insertions(+), 353 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/mangle64.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dc93b4c4af3..6839a5ec155 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,43 @@ +2014-10-14 DJ Delorie + + * machmode.h (int_n_data_t): New. + (int_n_enabled_p): New. + (int_n_data): New. + * tree.c (int_n_enabled_p): New. + (int_n_trees): New. + (make_or_reuse_type): Check for all __intN types, not just + __int128. + (build_common_tree_nodes): Likewise. Also fill in integer_typs[] + entries. + * tree.h (int128_integer_type_node): Remove. + (int128_unsigned_type_node): Remove. + (int_n_trees_t): New. + (int_n_enabled_p): New. + (int_n_trees): New. + * toplev.c (standard_type_bitsize): New. + (do_compile): Check which __intN types are enabled for the current + run. + * builtin-types.def (BT_INT128): Remove. + (BT_UINT128): Remove. + * machmode.def: Add macro to create __int128 for all targets. + * stor-layout.c (mode_for_size): Support __intN types. + (smallest_mode_for_size): Likewise. + (initialize_sizetypes): Support __intN types. + * genmodes.c (struct mode_data): Add int_n field. + (blank_mode): Likewise. + (INT_N): New. + (make_int_n): New. + (emit_insn_modes_h): Count __intN entries and define + NUM_INT_N_ENTS. + (emit_mode_int_n): New. + (emit_insn_modes_c): Call it. + * gimple.c (gimple_signed_or_unsigned_type): Check for all __intN + types, not just __int128. + * tree-core.h (integer_type_kind): Remove __int128-specific + entries, reserve spots for __intN entries. + + * config/msp430/msp430-modes.def (PSI): Add. + 2014-10-14 Kito Cheng * ira.c: Fix typo in comment. diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index f09c33547b8..6434bf2f19e 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -65,8 +65,6 @@ DEF_PRIMITIVE_TYPE (BT_LONG, long_integer_type_node) DEF_PRIMITIVE_TYPE (BT_ULONG, long_unsigned_type_node) DEF_PRIMITIVE_TYPE (BT_LONGLONG, long_long_integer_type_node) DEF_PRIMITIVE_TYPE (BT_ULONGLONG, long_long_unsigned_type_node) -DEF_PRIMITIVE_TYPE (BT_INT128, int128_integer_type_node) -DEF_PRIMITIVE_TYPE (BT_UINT128, int128_unsigned_type_node) DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node) DEF_PRIMITIVE_TYPE (BT_UINTMAX, uintmax_type_node) DEF_PRIMITIVE_TYPE (BT_UINT16, uint16_type_node) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index e579619245e..e6305351986 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,22 @@ +2014-10-14 DJ Delorie + + * c-pretty-print.c (pp_c_integer_constant): Check for all __intN + types, not just __int128. + * c-cppbuiltin.c (c_cpp_builtins): Add builtins for all __intN + types, not just __int128. + (cpp_atomic_builtins): Round pointer sizes up. + (type_suffix): Use type precision, not specific types. + * c-common.c (c_common_reswords): Remove __int128 special case. + (c_common_type_for_size): Check for all __intN types, not just + __int128. + (c_common_type_for_mode): Likewise. + (c_common_signed_or_unsigned_type): Likewise. + (c_build_bitfield_integer_type): Likewise. + (c_common_nodes_and_builtins): Likewise. + (keyword_begins_type_specifier): Likewise. + * c-common.h (rid): Remove RID_INT128 and add RID_INT_N_* for all + __intN variants. + 2014-10-12 Trevor Saunders * c-common.c: Use hash_table instead of hashtab. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 23163f51d67..cd73e272728 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -61,12 +61,10 @@ cpp_reader *parse_in; /* Declared in c-pragma.h. */ tree short_integer_type_node; tree long_integer_type_node; tree long_long_integer_type_node; - tree int128_integer_type_node; tree short_unsigned_type_node; tree long_unsigned_type_node; tree long_long_unsigned_type_node; - tree int128_unsigned_type_node; tree truthvalue_type_node; tree truthvalue_false_node; @@ -468,7 +466,6 @@ const struct c_common_resword c_common_reswords[] = { "__imag__", RID_IMAGPART, 0 }, { "__inline", RID_INLINE, 0 }, { "__inline__", RID_INLINE, 0 }, - { "__int128", RID_INT128, 0 }, { "__is_abstract", RID_IS_ABSTRACT, D_CXXONLY }, { "__is_base_of", RID_IS_BASE_OF, D_CXXONLY }, { "__is_class", RID_IS_CLASS, D_CXXONLY }, @@ -3449,6 +3446,8 @@ check_case_bounds (location_t loc, tree type, tree orig_type, tree c_common_type_for_size (unsigned int bits, int unsignedp) { + int i; + if (bits == TYPE_PRECISION (integer_type_node)) return unsignedp ? unsigned_type_node : integer_type_node; @@ -3465,10 +3464,11 @@ c_common_type_for_size (unsigned int bits, int unsignedp) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); - if (int128_integer_type_node - && bits == TYPE_PRECISION (int128_integer_type_node)) - return (unsignedp ? int128_unsigned_type_node - : int128_integer_type_node); + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i] + && bits == int_n_data[i].bitsize) + return (unsignedp ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type); if (bits == TYPE_PRECISION (widest_integer_literal_type_node)) return (unsignedp ? widest_unsigned_literal_type_node @@ -3532,6 +3532,7 @@ tree c_common_type_for_mode (enum machine_mode mode, int unsignedp) { tree t; + int i; if (mode == TYPE_MODE (integer_type_node)) return unsignedp ? unsigned_type_node : integer_type_node; @@ -3548,9 +3549,11 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp) if (mode == TYPE_MODE (long_long_integer_type_node)) return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node; - if (int128_integer_type_node - && mode == TYPE_MODE (int128_integer_type_node)) - return unsignedp ? int128_unsigned_type_node : int128_integer_type_node; + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i] + && mode == int_n_data[i].m) + return (unsignedp ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type); if (mode == TYPE_MODE (widest_integer_literal_type_node)) return unsignedp ? widest_unsigned_literal_type_node @@ -3748,6 +3751,7 @@ tree c_common_signed_or_unsigned_type (int unsignedp, tree type) { tree type1; + int i; /* This block of code emulates the behavior of the old c_common_unsigned_type. In particular, it returns @@ -3766,10 +3770,14 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type) return unsignedp ? long_unsigned_type_node : long_integer_type_node; if (type1 == long_long_integer_type_node || type1 == long_long_unsigned_type_node) return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node; - if (int128_integer_type_node - && (type1 == int128_integer_type_node - || type1 == int128_unsigned_type_node)) - return unsignedp ? int128_unsigned_type_node : int128_integer_type_node; + + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i] + && (type1 == int_n_trees[i].unsigned_type + || type1 == int_n_trees[i].signed_type)) + return (unsignedp ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type); + if (type1 == widest_integer_literal_type_node || type1 == widest_unsigned_literal_type_node) return unsignedp ? widest_unsigned_literal_type_node : widest_integer_literal_type_node; #if HOST_BITS_PER_WIDE_INT >= 64 @@ -3884,9 +3892,14 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type) if (TYPE_OK (long_long_integer_type_node)) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); - if (int128_integer_type_node && TYPE_OK (int128_integer_type_node)) - return (unsignedp ? int128_unsigned_type_node - : int128_integer_type_node); + + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i] + && TYPE_MODE (type) == int_n_data[i].m + && TYPE_PRECISION (type) == int_n_data[i].bitsize) + return (unsignedp ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type); + if (TYPE_OK (widest_integer_literal_type_node)) return (unsignedp ? widest_unsigned_literal_type_node : widest_integer_literal_type_node); @@ -3913,6 +3926,8 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type) tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp) { + int i; + /* Extended integer types of the same width as a standard type have lesser rank, so those of the same width as int promote to int or unsigned int and are valid for printf formats expecting int or @@ -3930,10 +3945,11 @@ c_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp) if (width == TYPE_PRECISION (long_long_integer_type_node)) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); - if (int128_integer_type_node - && width == TYPE_PRECISION (int128_integer_type_node)) - return (unsignedp ? int128_unsigned_type_node - : int128_integer_type_node); + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i] + && width == int_n_data[i].bitsize) + return (unsignedp ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type); return build_nonstandard_integer_type (width, unsignedp); } @@ -5338,6 +5354,7 @@ c_common_nodes_and_builtins (void) tree array_domain_type; tree va_list_ref_type_node; tree va_list_arg_type_node; + int i; build_common_tree_nodes (flag_signed_char, flag_short_double); @@ -5354,13 +5371,19 @@ c_common_nodes_and_builtins (void) record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node); record_builtin_type (RID_MAX, "long unsigned int", long_unsigned_type_node); - if (int128_integer_type_node != NULL_TREE) + + for (i = 0; i < NUM_INT_N_ENTS; i ++) { - record_builtin_type (RID_INT128, "__int128", - int128_integer_type_node); - record_builtin_type (RID_MAX, "__int128 unsigned", - int128_unsigned_type_node); + char name[25]; + + sprintf (name, "__int%d", int_n_data[i].bitsize); + record_builtin_type ((enum rid)(RID_FIRST_INT_N + i), xstrdup (name), + int_n_trees[i].signed_type); + sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); + record_builtin_type (RID_MAX, xstrdup (name), + int_n_trees[i].unsigned_type); } + if (c_dialect_cxx ()) record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node); record_builtin_type (RID_MAX, "long long int", @@ -5396,6 +5419,8 @@ c_common_nodes_and_builtins (void) TYPE_DECL, NULL_TREE, intDI_type_node)); #if HOST_BITS_PER_WIDE_INT >= 64 + /* Note that this is different than the __int128 type that's part of + the generic __intN support. */ if (targetm.scalar_mode_supported_p (TImode)) lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, TYPE_DECL, @@ -11762,7 +11787,6 @@ keyword_begins_type_specifier (enum rid keyword) case RID_FLOAT: case RID_DOUBLE: case RID_VOID: - case RID_INT128: case RID_UNSIGNED: case RID_LONG: case RID_SHORT: @@ -11785,6 +11809,10 @@ keyword_begins_type_specifier (enum rid keyword) case RID_ENUM: return true; default: + if (keyword >= RID_FIRST_INT_N + && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS + && int_n_enabled_p[keyword-RID_FIRST_INT_N]) + return true; return false; } } diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 1e3477f7058..fd94d64009a 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -91,7 +91,6 @@ enum rid /* C */ RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID, - RID_INT128, RID_ENUM, RID_STRUCT, RID_UNION, RID_IF, RID_ELSE, RID_WHILE, RID_DO, RID_FOR, RID_SWITCH, RID_CASE, RID_DEFAULT, RID_BREAK, RID_CONTINUE, RID_RETURN, RID_GOTO, @@ -190,6 +189,23 @@ enum rid RID_FIRST_ADDR_SPACE = RID_ADDR_SPACE_0, RID_LAST_ADDR_SPACE = RID_ADDR_SPACE_15, + /* __intN keywords. The _N_M here doesn't correspond to the intN + in the keyword; use the bitsize in int_n_t_data_t[M] for that. + For example, if int_n_t_data_t[0].bitsize is 13, then RID_INT_N_0 + is for __int13. */ + + /* Note that the range to use is RID_FIRST_INT_N through + RID_FIRST_INT_N + NUM_INT_N_ENTS - 1 and c-parser.c has a list of + all RID_INT_N_* in a case statement. */ + + RID_INT_N_0, + RID_INT_N_1, + RID_INT_N_2, + RID_INT_N_3, + + RID_FIRST_INT_N = RID_INT_N_0, + RID_LAST_INT_N = RID_INT_N_3, + RID_MAX, RID_FIRST_MODIFIER = RID_STATIC, diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 1173109fde7..aa61b7eb518 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -771,6 +771,8 @@ cpp_iec_559_complex_value (void) void c_cpp_builtins (cpp_reader *pfile) { + int i; + /* -undef turns off target-specific built-ins. */ if (flag_undef) return; @@ -889,6 +891,23 @@ c_cpp_builtins (cpp_reader *pfile) builtin_define_type_max ("__PTRDIFF_MAX__", ptrdiff_type_node); builtin_define_type_max ("__SIZE_MAX__", size_type_node); + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i]) + { + char buf[35+20+20]; + + /* These are used to configure the C++ library. */ + + if (!flag_iso || int_n_data[i].bitsize == POINTER_SIZE) + { + sprintf (buf, "__GLIBCXX_TYPE_INT_N_%d=__int%d", i, int_n_data[i].bitsize); + cpp_define (parse_in, buf); + + sprintf (buf, "__GLIBCXX_BITSIZE_INT_N_%d=%d", i, int_n_data[i].bitsize); + cpp_define (parse_in, buf); + } + } + /* stdint.h and the testsuite need to know these. */ builtin_define_stdint_macros (); @@ -1169,9 +1188,14 @@ c_cpp_builtins (cpp_reader *pfile) if (flag_openmp) cpp_define (pfile, "_OPENMP=201307"); - if (int128_integer_type_node != NULL_TREE) - builtin_define_type_sizeof ("__SIZEOF_INT128__", - int128_integer_type_node); + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i]) + { + char buf[15+20]; + sprintf(buf, "__SIZEOF_INT%d__", int_n_data[i].bitsize); + builtin_define_type_sizeof (buf, + int_n_trees[i].signed_type); + } builtin_define_type_sizeof ("__SIZEOF_WCHAR_T__", wchar_type_node); builtin_define_type_sizeof ("__SIZEOF_WINT_T__", wint_type_node); builtin_define_type_sizeof ("__SIZEOF_PTRDIFF_T__", @@ -1445,12 +1469,15 @@ type_suffix (tree type) static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" }; int unsigned_suffix; int is_long; + int tp = TYPE_PRECISION (type); if (type == long_long_integer_type_node - || type == long_long_unsigned_type_node) + || type == long_long_unsigned_type_node + || tp > TYPE_PRECISION (long_integer_type_node)) is_long = 2; else if (type == long_integer_type_node - || type == long_unsigned_type_node) + || type == long_unsigned_type_node + || tp > TYPE_PRECISION (integer_type_node)) is_long = 1; else if (type == integer_type_node || type == unsigned_type_node diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index 9ac8cbaa2a9..3b2dbc19ea6 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -920,6 +920,8 @@ pp_c_void_constant (c_pretty_printer *pp) static void pp_c_integer_constant (c_pretty_printer *pp, tree i) { + int idx; + /* We are going to compare the type of I to other types using pointer comparison so we need to use its canonical type. */ tree type = @@ -950,9 +952,17 @@ pp_c_integer_constant (c_pretty_printer *pp, tree i) else if (type == long_long_integer_type_node || type == long_long_unsigned_type_node) pp_string (pp, "ll"); - else if (type == int128_integer_type_node - || type == int128_unsigned_type_node) - pp_string (pp, "I128"); + else for (idx = 0; idx < NUM_INT_N_ENTS; idx ++) + if (int_n_enabled_p[idx]) + { + char buf[2+20]; + if (type == int_n_trees[idx].signed_type + || type == int_n_trees[idx].unsigned_type) + { + sprintf (buf, "I%d", int_n_data[idx].bitsize); + pp_string (pp, buf); + } + } } /* Print out a CHARACTER literal. */ diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index b4cc40a3762..690c3153c74 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,18 @@ +2014-10-14 DJ Delorie + + * c-parser.c (c_parse_init): Add RID entries for each __intN. + (c_token_starts_typename): Check all __intN, not just __int128. + (c_token_starts_declspecs): Likewise. + (c_parser_declspecs): Likewise. + (c_parser_attribute_any_word): Likewise. + (c_parser_objc_selector): Likewise. + * c-tree.h (c_typespec_keyword): cts_int128 -> cts_int_n. + (struct c_declspecs): Add int_n_idx field to record *which* __intN + is specified. + * c-decl.c (declspecs_add_type): Check for all __intN, not just + __int128. + (finish_declspecs): Likewise. + 2014-10-13 Anthony Brandon * c-parser.c (c_parser_all_labels): New function to replace diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index e23284a6cf0..2900c711b0b 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -9369,10 +9369,11 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, error_at (loc, ("both % and % in " "declaration specifiers")); - else if (specs->typespec_word == cts_int128) + else if (specs->typespec_word == cts_int_n) error_at (loc, - ("both % and %<__int128%> in " - "declaration specifiers")); + ("both % and %<__int%d%> in " + "declaration specifiers"), + int_n_data[specs->int_n_idx].bitsize); else if (specs->typespec_word == cts_bool) error_at (loc, ("both % and %<_Bool%> in " @@ -9417,10 +9418,11 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, error_at (loc, ("both % and % in " "declaration specifiers")); - else if (specs->typespec_word == cts_int128) + else if (specs->typespec_word == cts_int_n) error_at (loc, - ("both % and %<__int128%> in " - "declaration specifiers")); + ("both % and %<__int%d%> in " + "declaration specifiers"), + int_n_data[specs->int_n_idx].bitsize); else if (specs->typespec_word == cts_bool) error_at (loc, ("both % and %<_Bool%> in " @@ -9594,11 +9596,12 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, dupe = specs->saturating_p; pedwarn (loc, OPT_Wpedantic, "ISO C does not support saturating types"); - if (specs->typespec_word == cts_int128) + if (specs->typespec_word == cts_int_n) { error_at (loc, - ("both %<_Sat%> and %<__int128%> in " - "declaration specifiers")); + ("both %<_Sat%> and %<__int%d%> in " + "declaration specifiers"), + int_n_data[specs->int_n_idx].bitsize); } else if (specs->typespec_word == cts_auto_type) error_at (loc, @@ -9662,7 +9665,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, else { /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32", - "__int128", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or + "__intN", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or "__auto_type". */ if (specs->typespec_word != cts_none) { @@ -9703,31 +9706,41 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, specs->locations[cdw_typespec] = loc; } return specs; - case RID_INT128: - if (int128_integer_type_node == NULL_TREE) - { - error_at (loc, "%<__int128%> is not supported for this target"); - return specs; - } - if (!in_system_header_at (input_location)) + case RID_INT_N_0: + case RID_INT_N_1: + case RID_INT_N_2: + case RID_INT_N_3: + specs->int_n_idx = i - RID_INT_N_0; + if (!in_system_header_at (input_location) + /* As a special exception, allow a type that's used + for __SIZE_TYPE__. */ + && int_n_data[specs->int_n_idx].bitsize != POINTER_SIZE) pedwarn (loc, OPT_Wpedantic, - "ISO C does not support %<__int128%> type"); + "ISO C does not support %<__int%d%> types", + int_n_data[specs->int_n_idx].bitsize); if (specs->long_p) error_at (loc, - ("both %<__int128%> and % in " - "declaration specifiers")); + ("both %<__int%d%> and % in " + "declaration specifiers"), + int_n_data[specs->int_n_idx].bitsize); else if (specs->saturating_p) error_at (loc, - ("both %<_Sat%> and %<__int128%> in " - "declaration specifiers")); + ("both %<_Sat%> and %<__int%d%> in " + "declaration specifiers"), + int_n_data[specs->int_n_idx].bitsize); else if (specs->short_p) error_at (loc, - ("both %<__int128%> and % in " - "declaration specifiers")); + ("both %<__int%d%> and % in " + "declaration specifiers"), + int_n_data[specs->int_n_idx].bitsize); + else if (! int_n_enabled_p [specs->int_n_idx]) + error_at (loc, + "%<__int%d%> is not supported on this target", + int_n_data[specs->int_n_idx].bitsize); else { - specs->typespec_word = cts_int128; + specs->typespec_word = cts_int_n; specs->locations[cdw_typespec] = loc; } return specs; @@ -10295,12 +10308,12 @@ finish_declspecs (struct c_declspecs *specs) specs->type = build_complex_type (specs->type); } break; - case cts_int128: + case cts_int_n: gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p); gcc_assert (!(specs->signed_p && specs->unsigned_p)); specs->type = (specs->unsigned_p - ? int128_unsigned_type_node - : int128_integer_type_node); + ? int_n_trees[specs->int_n_idx].unsigned_type + : int_n_trees[specs->int_n_idx].signed_type); if (specs->complex_p) { pedwarn (specs->locations[cdw_complex], OPT_Wpedantic, diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 346448a149d..fa146de35d0 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -113,6 +113,16 @@ c_parse_init (void) C_IS_RESERVED_WORD (id) = 1; ridpointers [(int) c_common_reswords[i].rid] = id; } + + for (i = 0; i < NUM_INT_N_ENTS; i++) + { + /* We always create the symbols but they aren't always supported. */ + char name[50]; + sprintf (name, "__int%d", int_n_data[i].bitsize); + id = get_identifier (xstrdup (name)); + C_SET_RID_CODE (id, RID_FIRST_INT_N + i); + C_IS_RESERVED_WORD (id) = 1; + } } /* The C lexer intermediates between the lexer in cpplib and c-lex.c @@ -483,7 +493,6 @@ c_token_starts_typename (c_token *token) { case RID_UNSIGNED: case RID_LONG: - case RID_INT128: case RID_SHORT: case RID_SIGNED: case RID_COMPLEX: @@ -511,6 +520,10 @@ c_token_starts_typename (c_token *token) case RID_AUTO_TYPE: return true; default: + if (token->keyword >= RID_FIRST_INT_N + && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS + && int_n_enabled_p[token->keyword - RID_FIRST_INT_N]) + return true; return false; } case CPP_LESS: @@ -641,7 +654,6 @@ c_token_starts_declspecs (c_token *token) case RID_THREAD: case RID_UNSIGNED: case RID_LONG: - case RID_INT128: case RID_SHORT: case RID_SIGNED: case RID_COMPLEX: @@ -670,6 +682,10 @@ c_token_starts_declspecs (c_token *token) case RID_AUTO_TYPE: return true; default: + if (token->keyword >= RID_FIRST_INT_N + && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS + && int_n_enabled_p[token->keyword - RID_FIRST_INT_N]) + return true; return false; } case CPP_LESS: @@ -2158,7 +2174,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser) type-specifier: typeof-specifier __auto_type - __int128 + __intN _Decimal32 _Decimal64 _Decimal128 @@ -2312,7 +2328,6 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, /* Fall through. */ case RID_UNSIGNED: case RID_LONG: - case RID_INT128: case RID_SHORT: case RID_SIGNED: case RID_COMPLEX: @@ -2328,6 +2343,10 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, case RID_FRACT: case RID_ACCUM: case RID_SAT: + case RID_INT_N_0: + case RID_INT_N_1: + case RID_INT_N_2: + case RID_INT_N_3: if (!typespec_ok) goto out; attrs_ok = true; @@ -3738,7 +3757,6 @@ c_parser_attribute_any_word (c_parser *parser) case RID_STATIC: case RID_UNSIGNED: case RID_LONG: - case RID_INT128: case RID_CONST: case RID_EXTERN: case RID_REGISTER: @@ -3768,6 +3786,10 @@ c_parser_attribute_any_word (c_parser *parser) case RID_TRANSACTION_CANCEL: case RID_ATOMIC: case RID_AUTO_TYPE: + case RID_INT_N_0: + case RID_INT_N_1: + case RID_INT_N_2: + case RID_INT_N_3: ok = true; break; default: @@ -8992,7 +9014,6 @@ c_parser_objc_selector (c_parser *parser) case RID_ALIGNOF: case RID_UNSIGNED: case RID_LONG: - case RID_INT128: case RID_CONST: case RID_SHORT: case RID_VOLATILE: @@ -9013,6 +9034,10 @@ c_parser_objc_selector (c_parser *parser) case RID_BOOL: case RID_ATOMIC: case RID_AUTO_TYPE: + case RID_INT_N_0: + case RID_INT_N_1: + case RID_INT_N_2: + case RID_INT_N_3: c_parser_consume_token (parser); return value; default: diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index fc145a856d2..e6aca01923b 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -202,7 +202,7 @@ enum c_typespec_keyword { cts_char, cts_int, cts_float, - cts_int128, + cts_int_n, cts_double, cts_dfloat32, cts_dfloat64, @@ -269,6 +269,8 @@ struct c_declspecs { specifier, in bytes, or -1 if no such specifiers with nonzero alignment. */ int align_log; + /* For the __intN declspec, this stores the index into the int_n_* arrays. */ + int int_n_idx; /* The storage class specifier, or csc_none if none. */ enum c_storage_class storage_class; /* Any type specifier keyword used such as "int", not reflecting diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 50132ff1acb..00f5269fb68 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2014-10-14 DJ Delorie + + * typeck.c (cp_common_type): Check for all __intN types, not just + __int128. + * decl.c (grokdeclarator): Likewise. + * rtti.c (emit_support_tinfos): Check for all __intN types, not just + __int128. + * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): Check + for all __intN types, not just __int128. + (cp_parser_simple_type_specifier): Likewise. + * mangle.c (integer_type_codes): Remove int128-specific codes. + * cp-tree.h (cp_decl_specifier_seq): Add int_n_idx to store which + __intN was specified. + * lex.c (init_reswords): Reserve all __intN keywords. + 2014-10-14 Marc Glisse * typeck.c (cp_build_unary_op) [TRUTH_NOT_EXPR]: Accept float vectors. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index dbbf26daa11..ae135bee870 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4899,6 +4899,8 @@ typedef struct cp_decl_specifier_seq { /* The storage class specified -- or sc_none if no storage class was explicitly specified. */ cp_storage_class storage_class; + /* For the __intN declspec, this stores the index into the int_n_* arrays. */ + int int_n_idx; /* True iff TYPE_SPEC defines a class or enum. */ BOOL_BITFIELD type_definition_p : 1; /* True iff multiple types were (erroneously) specified for this @@ -4914,8 +4916,8 @@ typedef struct cp_decl_specifier_seq { BOOL_BITFIELD any_type_specifiers_p : 1; /* True iff "int" was explicitly provided. */ BOOL_BITFIELD explicit_int_p : 1; - /* True iff "__int128" was explicitly provided. */ - BOOL_BITFIELD explicit_int128_p : 1; + /* True iff "__intN" was explicitly provided. */ + BOOL_BITFIELD explicit_intN_p : 1; /* True iff "char" was explicitly provided. */ BOOL_BITFIELD explicit_char_p : 1; /* True iff ds_thread is set for __thread, not thread_local. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 88164cd8954..3eba4dcd1d6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8802,7 +8802,7 @@ grokdeclarator (const cp_declarator *declarator, { tree type = NULL_TREE; int longlong = 0; - int explicit_int128 = 0; + int explicit_intN = 0; int virtualp, explicitp, friendp, inlinep, staticp; int explicit_int = 0; int explicit_char = 0; @@ -8875,7 +8875,7 @@ grokdeclarator (const cp_declarator *declarator, short_p = decl_spec_seq_has_spec_p (declspecs, ds_short); long_p = decl_spec_seq_has_spec_p (declspecs, ds_long); longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long); - explicit_int128 = declspecs->explicit_int128_p; + explicit_intN = declspecs->explicit_intN_p; thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread); if (decl_context == FUNCDEF) @@ -9221,16 +9221,18 @@ grokdeclarator (const cp_declarator *declarator, ctype = NULL_TREE; - if (explicit_int128) + if (explicit_intN) { - if (int128_integer_type_node == NULL_TREE) - { - error ("%<__int128%> is not supported by this target"); - explicit_int128 = false; - } + if (! int_n_enabled_p[declspecs->int_n_idx]) + { + error ("%<__int%d%> is not supported by this target", + int_n_data[declspecs->int_n_idx].bitsize); + explicit_intN = false; + } else if (pedantic && ! in_system_header_at (input_location)) - pedwarn (input_location, OPT_Wpedantic, - "ISO C++ does not support %<__int128%> for %qs", name); + pedwarn (input_location, OPT_Wpedantic, + "ISO C++ does not support %<__int%d%> for %qs", + int_n_data[declspecs->int_n_idx].bitsize, name); } /* Now process the modifiers that were specified @@ -9262,7 +9264,7 @@ grokdeclarator (const cp_declarator *declarator, error ("% invalid for %qs", name); else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE) error ("% or % invalid for %qs", name); - else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128) + else if ((long_p || short_p || explicit_char || explicit_int) && explicit_intN) error ("%, %, %, or % invalid for %qs", name); else if ((long_p || short_p) && explicit_char) error ("% or % specified with char for %qs", name); @@ -9278,7 +9280,7 @@ grokdeclarator (const cp_declarator *declarator, else { ok = 1; - if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic) + if (!explicit_int && !defaulted_int && !explicit_char && !explicit_intN && pedantic) { pedwarn (input_location, OPT_Wpedantic, "long, short, signed or unsigned used invalidly for %qs", @@ -9320,8 +9322,8 @@ grokdeclarator (const cp_declarator *declarator, && TREE_CODE (type) == INTEGER_TYPE && !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node))) { - if (explicit_int128) - type = int128_unsigned_type_node; + if (explicit_intN) + type = int_n_trees[declspecs->int_n_idx].unsigned_type; else if (longlong) type = long_long_unsigned_type_node; else if (long_p) @@ -9337,8 +9339,8 @@ grokdeclarator (const cp_declarator *declarator, } else if (signed_p && type == char_type_node) type = signed_char_type_node; - else if (explicit_int128) - type = int128_integer_type_node; + else if (explicit_intN) + type = int_n_trees[declspecs->int_n_idx].signed_type; else if (longlong) type = long_long_integer_type_node; else if (long_p) @@ -9354,7 +9356,7 @@ grokdeclarator (const cp_declarator *declarator, "complex double", but if any modifiers at all are specified it is the complex form of TYPE. E.g, "complex short" is "complex short int". */ - else if (defaulted_int && ! longlong && ! explicit_int128 + else if (defaulted_int && ! longlong && ! explicit_intN && ! (long_p || short_p || signed_p || unsigned_p)) type = complex_double_type_node; else if (type == integer_type_node) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 57b779d77e1..fd4f9241188 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -193,6 +193,15 @@ init_reswords (void) if (! (c_common_reswords[i].disable & mask)) C_IS_RESERVED_WORD (id) = 1; } + + for (i = 0; i < NUM_INT_N_ENTS; i++) + { + char name[50]; + sprintf (name, "__int%d", int_n_data[i].bitsize); + id = get_identifier (name); + C_SET_RID_CODE (id, RID_FIRST_INT_N + i); + C_IS_RESERVED_WORD (id) = 1; + } } static void diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 445acd75ad7..55f508a272a 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -154,8 +154,8 @@ integer_type_codes[itk_none] = 'm', /* itk_unsigned_long */ 'x', /* itk_long_long */ 'y', /* itk_unsigned_long_long */ - 'n', /* itk_int128 */ - 'o', /* itk_unsigned_int128 */ + /* __intN types are handled separately */ + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }; static int decl_is_template_id (const tree, tree* const); @@ -2215,6 +2215,7 @@ write_builtin_type (tree type) iagain: for (itk = 0; itk < itk_none; ++itk) if (integer_types[itk] != NULL_TREE + && integer_type_codes[itk] != '\0' && type == integer_types[itk]) { /* Print the corresponding single-letter code. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c6218af21e9..b5a3724378f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -947,7 +947,6 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer) case RID_SHORT: case RID_INT: case RID_LONG: - case RID_INT128: case RID_SIGNED: case RID_UNSIGNED: case RID_FLOAT: @@ -962,6 +961,10 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer) return true; default: + if (token->keyword >= RID_FIRST_INT_N + && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS + && int_n_enabled_p[token->keyword - RID_FIRST_INT_N]) + return true; return false; } } @@ -14664,6 +14667,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, { tree type = NULL_TREE; cp_token *token; + int idx; /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); @@ -14697,12 +14701,19 @@ cp_parser_simple_type_specifier (cp_parser* parser, decl_specs->explicit_int_p = true; type = integer_type_node; break; - case RID_INT128: - if (!int128_integer_type_node) + case RID_INT_N_0: + case RID_INT_N_1: + case RID_INT_N_2: + case RID_INT_N_3: + idx = token->keyword - RID_INT_N_0; + if (! int_n_enabled_p [idx]) break; if (decl_specs) - decl_specs->explicit_int128_p = true; - type = int128_integer_type_node; + { + decl_specs->explicit_intN_p = true; + decl_specs->int_n_idx = idx; + } + type = int_n_trees [idx].signed_type; break; case RID_LONG: if (decl_specs) diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 762953b38a0..0d6dd960003 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1520,7 +1520,6 @@ emit_support_tinfos (void) &integer_type_node, &unsigned_type_node, &long_integer_type_node, &long_unsigned_type_node, &long_long_integer_type_node, &long_long_unsigned_type_node, - &int128_integer_type_node, &int128_unsigned_type_node, &float_type_node, &double_type_node, &long_double_type_node, &dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node, &nullptr_type_node, @@ -1542,6 +1541,12 @@ emit_support_tinfos (void) doing_runtime = 1; for (ix = 0; fundamentals[ix]; ix++) emit_support_tinfo_1 (*fundamentals[ix]); + for (ix = 0; ix < NUM_INT_N_ENTS; ix ++) + if (int_n_enabled_p[ix]) + { + emit_support_tinfo_1 (int_n_trees[ix].signed_type); + emit_support_tinfo_1 (int_n_trees[ix].unsigned_type); + } } /* Finish a type info decl. DECL_PTR is a pointer to an unemitted diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5b4f5332a34..bc30a0800e1 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -270,6 +270,7 @@ cp_common_type (tree t1, tree t2) enum tree_code code1 = TREE_CODE (t1); enum tree_code code2 = TREE_CODE (t2); tree attributes; + int i; /* In what follows, we slightly generalize the rules given in [expr] so @@ -364,16 +365,19 @@ cp_common_type (tree t1, tree t2) : long_long_integer_type_node); return build_type_attribute_variant (t, attributes); } - if (int128_integer_type_node != NULL_TREE - && (same_type_p (TYPE_MAIN_VARIANT (t1), - int128_integer_type_node) - || same_type_p (TYPE_MAIN_VARIANT (t2), - int128_integer_type_node))) + for (i = 0; i < NUM_INT_N_ENTS; i ++) { - tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2)) - ? int128_unsigned_type_node - : int128_integer_type_node); - return build_type_attribute_variant (t, attributes); + if (int_n_enabled_p [i] + && (same_type_p (TYPE_MAIN_VARIANT (t1), + int_n_trees[i].signed_type) + || same_type_p (TYPE_MAIN_VARIANT (t2), + int_n_trees[i].signed_type))) + { + tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2)) + ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type); + return build_type_attribute_variant (t, attributes); + } } /* Go through the same procedure, but for longs. */ diff --git a/gcc/genmodes.c b/gcc/genmodes.c index 0215a1883c8..1a32cdefeab 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -74,6 +74,7 @@ struct mode_data unsigned int fbit; /* the number of fractional bits */ bool need_bytesize_adj; /* true if this mode need dynamic size adjustment */ + unsigned int int_n; /* If nonzero, then __int will be defined */ }; static struct mode_data *modes[MAX_MODE_CLASS]; @@ -84,7 +85,7 @@ static const struct mode_data blank_mode = { 0, "", MAX_MODE_CLASS, -1U, -1U, -1U, -1U, 0, 0, 0, 0, 0, - "", 0, 0, 0, 0, false + "", 0, 0, 0, 0, false, 0 }; static htab_t modes_by_name; @@ -632,6 +633,34 @@ reset_float_format (const char *name, const char *format, m->format = format; } +/* __intN support. */ +#define INT_N(M,PREC) \ + make_int_n (#M, PREC, __FILE__, __LINE__) +static void ATTRIBUTE_UNUSED +make_int_n (const char *m, int bitsize, + const char *file, unsigned int line) +{ + struct mode_data *component = find_mode (m); + if (!component) + { + error ("%s:%d: no mode \"%s\"", file, line, m); + return; + } + if (component->cl != MODE_INT + && component->cl != MODE_PARTIAL_INT) + { + error ("%s:%d: mode \"%s\" is not class INT or PARTIAL_INT", file, line, m); + return; + } + if (component->int_n != 0) + { + error ("%s:%d: mode \"%s\" already has an intN", file, line, m); + return; + } + + component->int_n = bitsize; +} + /* Partial integer modes are specified by relation to a full integer mode. */ #define PARTIAL_INT_MODE(M,PREC,NAME) \ @@ -1010,6 +1039,7 @@ emit_insn_modes_h (void) { int c; struct mode_data *m, *first, *last; + int n_int_n_ents = 0; printf ("/* Generated automatically from machmode.def%s%s\n", HAVE_EXTRA_MODES ? " and " : "", @@ -1071,6 +1101,13 @@ enum machine_mode\n{"); printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const"); printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const"); emit_max_int (); + + for_all_modes (c, m) + if (m->int_n) + n_int_n_ents ++; + + printf ("#define NUM_INT_N_ENTS %d\n", n_int_n_ents); + puts ("\n#if GCC_VERSION >= 4001\n"); emit_mode_size_inline (); emit_mode_nunits_inline (); @@ -1520,6 +1557,53 @@ emit_mode_fbit (void) print_closer (); } +/* Emit __intN for all modes. */ + +static void +emit_mode_int_n (void) +{ + int c; + struct mode_data *m; + struct mode_data **mode_sort; + int n_modes = 0; + int i, j; + + print_decl ("int_n_data_t", "int_n_data", ""); + + n_modes = 0; + for_all_modes (c, m) + if (m->int_n) + n_modes ++; + mode_sort = XALLOCAVEC (struct mode_data *, n_modes); + + n_modes = 0; + for_all_modes (c, m) + if (m->int_n) + mode_sort[n_modes++] = m; + + /* Yes, this is a bubblesort, but there are at most four (and + usually only 1-2) entries to sort. */ + for (i = 0; iint_n > mode_sort[j]->int_n) + { + m = mode_sort[i]; + mode_sort[i] = mode_sort[j]; + mode_sort[j] = m; + } + + for (i = 0; i < n_modes; i ++) + { + m = mode_sort[i]; + printf(" {\n"); + tagged_printf ("%u", m->int_n, m->name); + printf ("%smode,", m->name); + printf(" },\n"); + } + + print_closer (); +} + static void emit_insn_modes_c (void) @@ -1539,6 +1623,7 @@ emit_insn_modes_c (void) emit_mode_adjustments (); emit_mode_ibit (); emit_mode_fbit (); + emit_mode_int_n (); } static void diff --git a/gcc/gimple.c b/gcc/gimple.c index db7617418e5..da993214ef8 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -2113,6 +2113,7 @@ static tree gimple_signed_or_unsigned_type (bool unsignedp, tree type) { tree type1; + int i; type1 = TYPE_MAIN_VARIANT (type); if (type1 == signed_char_type_node @@ -2130,10 +2131,15 @@ gimple_signed_or_unsigned_type (bool unsignedp, tree type) return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node; - if (int128_integer_type_node && (type1 == int128_integer_type_node || type1 == int128_unsigned_type_node)) - return unsignedp - ? int128_unsigned_type_node - : int128_integer_type_node; + + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i] + && (type1 == int_n_trees[i].unsigned_type + || type1 == int_n_trees[i].signed_type)) + return unsignedp + ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type; + #if HOST_BITS_PER_WIDE_INT >= 64 if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node) return unsignedp ? unsigned_intTI_type_node : intTI_type_node; @@ -2246,10 +2252,14 @@ gimple_signed_or_unsigned_type (bool unsignedp, tree type) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); - if (int128_integer_type_node && TYPE_OK (int128_integer_type_node)) - return (unsignedp - ? int128_unsigned_type_node - : int128_integer_type_node); + + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i] + && TYPE_MODE (type) == int_n_data[i].m + && TYPE_PRECISION (type) == int_n_data[i].bitsize) + return unsignedp + ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type; #if HOST_BITS_PER_WIDE_INT >= 64 if (TYPE_OK (intTI_type_node)) diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index fba61ef4ff7..7ae4d8a54a3 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2014-10-14 DJ Delorie + + * lto-lang.c (lto_build_c_type_nodes): Check intN types for + size-type as well. + (lto_init): Initialize all intN types, not just int128. + 2014-10-06 Martin Liska * lto.c (stream_out): ARG_UNUSED added for last argument. diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index 9e8524acac2..3a295308aa6 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -1150,7 +1150,26 @@ lto_build_c_type_nodes (void) signed_size_type_node = long_long_integer_type_node; } else - gcc_unreachable (); + { + int i; + + signed_size_type_node = NULL_TREE; + for (i = 0; i < NUM_INT_N_ENTS; i++) + if (int_n_enabled_p[i]) + { + char name[50]; + sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); + + if (strcmp (name, SIZE_TYPE) == 0) + { + intmax_type_node = int_n_trees[i].signed_type; + uintmax_type_node = int_n_trees[i].unsigned_type; + signed_size_type_node = int_n_trees[i].signed_type; + } + } + if (signed_size_type_node == NULL_TREE) + gcc_unreachable (); + } wint_type_node = unsigned_type_node; pid_type_node = integer_type_node; @@ -1161,6 +1180,8 @@ lto_build_c_type_nodes (void) static bool lto_init (void) { + int i; + /* We need to generate LTO if running in WPA mode. */ flag_generate_lto = (flag_wpa != NULL); @@ -1232,8 +1253,13 @@ lto_init (void) NAME_TYPE (complex_float_type_node, "complex float"); NAME_TYPE (complex_double_type_node, "complex double"); NAME_TYPE (complex_long_double_type_node, "complex long double"); - if (int128_integer_type_node) - NAME_TYPE (int128_integer_type_node, "__int128"); + for (i = 0; i < NUM_INT_N_ENTS; i++) + if (int_n_enabled_p[i]) + { + char name[50]; + sprintf (name, "__int%d", int_n_data[i].bitsize); + NAME_TYPE (int_n_trees[i].signed_type, name); + } #undef NAME_TYPE /* Initialize LTO-specific data structures. */ diff --git a/gcc/machmode.def b/gcc/machmode.def index 38d3b01872f..bfa0605a966 100644 --- a/gcc/machmode.def +++ b/gcc/machmode.def @@ -192,6 +192,13 @@ INT_MODE (TI, 16); /* No partial integer modes are defined by default. */ +/* The target normally defines any target-specific __intN types and + their modes, but __int128 for TImode is fairly common so define it + here. The type will not be created unless the target supports + TImode. */ + +INT_N (TI, 128); + /* Basic floating point modes. SF and DF are the only modes provided by default. The names QF, HF, XF, and TF are reserved for targets that need 1-word, 2-word, 80-bit, or 128-bit float types respectively. diff --git a/gcc/machmode.h b/gcc/machmode.h index 8d6ea187b4d..27a38d36aae 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -345,4 +345,16 @@ extern void init_adjust_machine_modes (void); (SCALAR_INT_MODE_P (MODE) \ && GET_MODE_PRECISION (MODE) <= HOST_BITS_PER_WIDE_INT) +typedef struct { + /* These parts are initailized by genmodes output */ + unsigned int bitsize; + enum machine_mode m; + /* RID_* is RID_INTN_BASE + index into this array */ +} int_n_data_t; + +/* This is also in tree.h. genmodes.c guarantees the're sorted from + smallest bitsize to largest bitsize. */ +extern bool int_n_enabled_p[NUM_INT_N_ENTS]; +extern const int_n_data_t int_n_data[NUM_INT_N_ENTS]; + #endif /* not HAVE_MACHINE_MODES */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index eefc52a5893..c7b524c574c 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -313,6 +313,7 @@ enum machine_mode mode_for_size (unsigned int size, enum mode_class mclass, int limit) { enum machine_mode mode; + int i; if (limit && size > MAX_FIXED_MODE_SIZE) return BLKmode; @@ -323,6 +324,12 @@ mode_for_size (unsigned int size, enum mode_class mclass, int limit) if (GET_MODE_PRECISION (mode) == size) return mode; + if (mclass == MODE_INT || mclass == MODE_PARTIAL_INT) + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_data[i].bitsize == size + && int_n_enabled_p[i]) + return int_n_data[i].m; + return BLKmode; } @@ -349,16 +356,27 @@ mode_for_size_tree (const_tree size, enum mode_class mclass, int limit) enum machine_mode smallest_mode_for_size (unsigned int size, enum mode_class mclass) { - enum machine_mode mode; + enum machine_mode mode = VOIDmode; + int i; /* Get the first mode which has at least this size, in the specified class. */ for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) if (GET_MODE_PRECISION (mode) >= size) - return mode; + break; - gcc_unreachable (); + if (mclass == MODE_INT || mclass == MODE_PARTIAL_INT) + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_data[i].bitsize >= size + && int_n_data[i].bitsize < GET_MODE_PRECISION (mode) + && int_n_enabled_p[i]) + mode = int_n_data[i].m; + + if (mode == VOIDmode) + gcc_unreachable (); + + return mode; } /* Find an integer mode of the exact same size, or BLKmode on failure. */ @@ -2550,7 +2568,24 @@ initialize_sizetypes (void) else if (strcmp (SIZETYPE, "short unsigned int") == 0) precision = SHORT_TYPE_SIZE; else - gcc_unreachable (); + { + int i; + + precision = -1; + for (i = 0; i < NUM_INT_N_ENTS; i++) + if (int_n_enabled_p[i]) + { + char name[50]; + sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); + + if (strcmp (name, SIZETYPE) == 0) + { + precision = int_n_data[i].bitsize; + } + } + if (precision == -1) + gcc_unreachable (); + } bprecision = MIN (precision + BITS_PER_UNIT_LOG + 1, MAX_FIXED_MODE_SIZE); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2f08ffe1c11..7ef5e8a76af 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-10-14 DJ Delorie + + * g++.dg/abi/mangle64.C: New. + 2014-10-14 Marc Glisse * g++.dg/ext/vector9.C: Test ! with float vectors. diff --git a/gcc/testsuite/g++.dg/abi/mangle64.C b/gcc/testsuite/g++.dg/abi/mangle64.C new file mode 100644 index 00000000000..778cda70dd1 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle64.C @@ -0,0 +1,13 @@ +// { dg-do compile { target msp430*-*-* } } +// { dg-options "-std=gnu++11" } +// { dg-skip-if "" { msp430*-*-* } { "-mcpu=msp430" } { "" } } + +__int20 x; + +__int20 foo (__int20 a, unsigned __int20 b) +{ + return a + b; +} + +// { dg-final { scan-assembler "\n_?_Z3foou5int20u6uint20\[: \t\n\]" } } + diff --git a/gcc/toplev.c b/gcc/toplev.c index 0e626b34b8f..f7a5035fdce 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1901,6 +1901,21 @@ finalize (bool no_backend) lang_hooks.finish (); } +static bool +standard_type_bitsize (int bitsize) +{ + /* As a special exception, we always want __int128 enabled if possible. */ + if (bitsize == 128) + return false; + if (bitsize == CHAR_TYPE_SIZE + || bitsize == SHORT_TYPE_SIZE + || bitsize == INT_TYPE_SIZE + || bitsize == LONG_TYPE_SIZE + || bitsize == LONG_LONG_TYPE_SIZE) + return true; + return false; +} + /* Initialize the compiler, and compile the input file. */ static void do_compile (void) @@ -1916,6 +1931,8 @@ do_compile (void) /* Don't do any more if an error has already occurred. */ if (!seen_error ()) { + int i; + timevar_start (TV_PHASE_SETUP); /* This must be run always, because it is needed to compute the FP @@ -1924,6 +1941,16 @@ do_compile (void) init_adjust_machine_modes (); init_derived_machine_modes (); + /* This must happen after the backend has a chance to process + command line options, but before the parsers are + initialized. */ + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (targetm.scalar_mode_supported_p (int_n_data[i].m) + && ! standard_type_bitsize (int_n_data[i].bitsize)) + int_n_enabled_p[i] = true; + else + int_n_enabled_p[i] = false; + /* Set up the back-end if requested. */ if (!no_backend) backend_init (); diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 0761f95df45..c9004fd9771 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -570,8 +570,16 @@ enum integer_type_kind { itk_unsigned_long, itk_long_long, itk_unsigned_long_long, - itk_int128, - itk_unsigned_int128, + + itk_intN_0, + itk_unsigned_intN_0, + itk_intN_1, + itk_unsigned_intN_1, + itk_intN_2, + itk_unsigned_intN_2, + itk_intN_3, + itk_unsigned_intN_3, + itk_none }; diff --git a/gcc/tree.c b/gcc/tree.c index 2f4d194dee5..e7032065da0 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -236,6 +236,9 @@ static void attribute_hash_list (const_tree, inchash::hash &); tree global_trees[TI_MAX]; tree integer_types[itk_none]; +bool int_n_enabled_p[NUM_INT_N_ENTS]; +struct int_n_trees_t int_n_trees [NUM_INT_N_ENTS]; + unsigned char tree_contains_struct[MAX_TREE_CODES][64]; /* Number of operands for each OpenMP clause. */ @@ -9445,6 +9448,8 @@ make_vector_type (tree innertype, int nunits, enum machine_mode mode) static tree make_or_reuse_type (unsigned size, int unsignedp) { + int i; + if (size == INT_TYPE_SIZE) return unsignedp ? unsigned_type_node : integer_type_node; if (size == CHAR_TYPE_SIZE) @@ -9456,9 +9461,12 @@ make_or_reuse_type (unsigned size, int unsignedp) if (size == LONG_LONG_TYPE_SIZE) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); - if (size == 128 && int128_integer_type_node) - return (unsignedp ? int128_unsigned_type_node - : int128_integer_type_node); + + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (size == int_n_data[i].bitsize + && int_n_enabled_p[i]) + return (unsignedp ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type); if (unsignedp) return make_unsigned_type (size); @@ -9574,6 +9582,8 @@ build_atomic_base (tree type, unsigned int align) void build_common_tree_nodes (bool signed_char, bool short_double) { + int i; + error_mark_node = make_node (ERROR_MARK); TREE_TYPE (error_mark_node) = error_mark_node; @@ -9601,17 +9611,20 @@ build_common_tree_nodes (bool signed_char, bool short_double) long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE); long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE); long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE); -#if HOST_BITS_PER_WIDE_INT >= 64 - /* TODO: This isn't correct, but as logic depends at the moment on - host's instead of target's wide-integer. - If there is a target not supporting TImode, but has an 128-bit - integer-scalar register, this target check needs to be adjusted. */ - if (targetm.scalar_mode_supported_p (TImode)) - { - int128_integer_type_node = make_signed_type (128); - int128_unsigned_type_node = make_unsigned_type (128); - } -#endif + + for (i = 0; i < NUM_INT_N_ENTS; i ++) + { + int_n_trees[i].signed_type = make_signed_type (int_n_data[i].bitsize); + int_n_trees[i].unsigned_type = make_unsigned_type (int_n_data[i].bitsize); + TYPE_SIZE (int_n_trees[i].signed_type) = bitsize_int (int_n_data[i].bitsize); + TYPE_SIZE (int_n_trees[i].unsigned_type) = bitsize_int (int_n_data[i].bitsize); + + if (int_n_data[i].bitsize > LONG_LONG_TYPE_SIZE) + { + integer_types[itk_intN_0 + i * 2] = int_n_trees[i].signed_type; + integer_types[itk_unsigned_intN_0 + i * 2] = int_n_trees[i].unsigned_type; + } + } /* Define a boolean type. This type only represents boolean values but may be larger than char depending on the value of BOOL_TYPE_SIZE. */ @@ -9630,7 +9643,24 @@ build_common_tree_nodes (bool signed_char, bool short_double) else if (strcmp (SIZE_TYPE, "short unsigned int") == 0) size_type_node = short_unsigned_type_node; else - gcc_unreachable (); + { + int i; + + size_type_node = NULL_TREE; + for (i = 0; i < NUM_INT_N_ENTS; i++) + if (int_n_enabled_p[i]) + { + char name[50]; + sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); + + if (strcmp (name, SIZE_TYPE) == 0) + { + size_type_node = int_n_trees[i].unsigned_type; + } + } + if (size_type_node == NULL_TREE) + gcc_unreachable (); + } /* Fill in the rest of the sized types. Reuse existing type nodes when possible. */ diff --git a/gcc/tree.h b/gcc/tree.h index 254129a420a..45f127fd644 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3426,8 +3426,6 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, #define long_unsigned_type_node integer_types[itk_unsigned_long] #define long_long_integer_type_node integer_types[itk_long_long] #define long_long_unsigned_type_node integer_types[itk_unsigned_long_long] -#define int128_integer_type_node integer_types[itk_int128] -#define int128_unsigned_type_node integer_types[itk_unsigned_int128] /* True if NODE is an erroneous expression. */ @@ -4800,6 +4798,17 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ extern tree array_ref_low_bound (tree); + +struct GTY(()) int_n_trees_t { + /* These parts are initialized at runtime */ + tree signed_type; + tree unsigned_type; +}; + +/* This is also in machmode.h */ +extern bool int_n_enabled_p[NUM_INT_N_ENTS]; +extern GTY(()) struct int_n_trees_t int_n_trees[NUM_INT_N_ENTS]; + /* Like bit_position, but return as an integer. It must be representable in that way (since it could be a signed value, we don't have the option of returning -1 like int_size_in_byte can. */ diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a20ae1ccade..cc052f082b5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2014-10-14 DJ Delorie + + * src/c++11/limits.cc: Add support for __intN types. + * include/std/type_traits: Likewise. + * include/std/limits: Likewise. + * include/c_std/cstdlib: Likewise. + * include/bits/cpp_type_traits.h: Likewise. + * include/c_global/cstdlib: Likewise. + 2014-10-14 Jonathan Wakely * testsuite/20_util/align/1.cc: Add dg-require-stdint. diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h index 8df81a705ea..46067f18a1e 100644 --- a/libstdc++-v3/include/bits/cpp_type_traits.h +++ b/libstdc++-v3/include/bits/cpp_type_traits.h @@ -141,7 +141,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Thirteen specializations (yes there are eleven standard integer // types; long long and unsigned long long are - // supported as extensions) + // supported as extensions). Up to four target-specific __int + // types are supported as well. template<> struct __is_integer { @@ -251,6 +252,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef __true_type __type; }; +#define __INT_N(TYPE) \ + template<> \ + struct __is_integer \ + { \ + enum { __value = 1 }; \ + typedef __true_type __type; \ + }; \ + template<> \ + struct __is_integer \ + { \ + enum { __value = 1 }; \ + typedef __true_type __type; \ + }; + +#ifdef __GLIBCXX_TYPE_INT_N_0 +__INT_N(__GLIBCXX_TYPE_INT_N_0) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_1 +__INT_N(__GLIBCXX_TYPE_INT_N_1) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_2 +__INT_N(__GLIBCXX_TYPE_INT_N_2) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_3 +__INT_N(__GLIBCXX_TYPE_INT_N_3) +#endif + +#undef __INT_N + // // Floating point types // diff --git a/libstdc++-v3/include/c_global/cstdlib b/libstdc++-v3/include/c_global/cstdlib index e98a7262817..f1b36f3db61 100644 --- a/libstdc++-v3/include/c_global/cstdlib +++ b/libstdc++-v3/include/c_global/cstdlib @@ -174,10 +174,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION abs(long long __x) { return __builtin_llabs (__x); } #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) - inline __int128 - abs(__int128 __x) { return __x >= 0 ? __x : -__x; } +#if defined(__GLIBCXX_TYPE_INT_N_0) + inline __GLIBCXX_TYPE_INT_N_0 + abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } #endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + inline __GLIBCXX_TYPE_INT_N_1 + abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) + inline __GLIBCXX_TYPE_INT_N_2 + abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) + inline __GLIBCXX_TYPE_INT_N_3 + abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; } +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/c_std/cstdlib b/libstdc++-v3/include/c_std/cstdlib index 7f0d9b20cd1..38c942a3ceb 100644 --- a/libstdc++-v3/include/c_std/cstdlib +++ b/libstdc++-v3/include/c_std/cstdlib @@ -169,9 +169,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION abs(long long __x) { return __builtin_llabs (__x); } #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) - inline __int128 - abs(__int128 __x) { return __x >= 0 ? __x : -__x; } +#if defined(__GLIBCXX_TYPE_INT_N_0) + inline __GLIBCXX_TYPE_INT_N_0 + abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + inline __GLIBCXX_TYPE_INT_N_1 + abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) + inline __GLIBCXX_TYPE_INT_N_2 + abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) + inline __GLIBCXX_TYPE_INT_N_3 + abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; } #endif inline ldiv_t diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits index f39821eb365..d5add09655a 100644 --- a/libstdc++-v3/include/std/limits +++ b/libstdc++-v3/include/std/limits @@ -125,21 +125,32 @@ // You should not need to define any macros below this point. -#define __glibcxx_signed(T) ((T)(-1) < 0) +#define __glibcxx_signed_b(T,B) ((T)(-1) < 0) -#define __glibcxx_min(T) \ - (__glibcxx_signed (T) ? -__glibcxx_max (T) - 1 : (T)0) +#define __glibcxx_min_b(T,B) \ + (__glibcxx_signed_b (T,B) ? -__glibcxx_max_b (T,B) - 1 : (T)0) -#define __glibcxx_max(T) \ - (__glibcxx_signed (T) ? \ - (((((T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0) +#define __glibcxx_max_b(T,B) \ + (__glibcxx_signed_b (T,B) ? \ + (((((T)1 << (__glibcxx_digits_b (T,B) - 1)) - 1) << 1) + 1) : ~(T)0) -#define __glibcxx_digits(T) \ - (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T)) +#define __glibcxx_digits_b(T,B) \ + (B - __glibcxx_signed_b (T,B)) // The fraction 643/2136 approximates log10(2) to 7 significant digits. +#define __glibcxx_digits10_b(T,B) \ + (__glibcxx_digits_b (T,B) * 643L / 2136) + +#define __glibcxx_signed(T) \ + __glibcxx_signed_b (T, sizeof(T) * __CHAR_BIT__) +#define __glibcxx_min(T) \ + __glibcxx_min_b (T, sizeof(T) * __CHAR_BIT__) +#define __glibcxx_max(T) \ + __glibcxx_max_b (T, sizeof(T) * __CHAR_BIT__) +#define __glibcxx_digits(T) \ + __glibcxx_digits_b (T, sizeof(T) * __CHAR_BIT__) #define __glibcxx_digits10(T) \ - (__glibcxx_digits (T) * 643L / 2136) + __glibcxx_digits10_b (T, sizeof(T) * __CHAR_BIT__) #define __glibcxx_max_digits10(T) \ (2 + (T) * 643L / 2136) @@ -1399,153 +1410,181 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION = round_toward_zero; }; -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) - /// numeric_limits<__int128> specialization. - template<> - struct numeric_limits<__int128> - { - static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; - - static _GLIBCXX_CONSTEXPR __int128 - min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min (__int128); } - - static _GLIBCXX_CONSTEXPR __int128 - max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (__int128); } +#if !defined(__STRICT_ANSI__) + +#define __INT_N(TYPE, BITSIZE, EXT, UEXT) \ + template<> \ + struct numeric_limits \ + { \ + static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min_b (TYPE, BITSIZE); } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE);; } \ + \ + static _GLIBCXX_USE_CONSTEXPR int digits \ + = BITSIZE - 1; \ + static _GLIBCXX_USE_CONSTEXPR int digits10 \ + = (BITSIZE - 1) * 643L / 2136; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; \ + static _GLIBCXX_USE_CONSTEXPR int radix = 2; \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + EXT \ + \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; \ + static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; \ + static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; \ + static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \ + = denorm_absent; \ + static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + infinity() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast(0); } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + quiet_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast(0); } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + signaling_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast(0); } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + denorm_min() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast(0); } \ + \ + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; \ + static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool traps \ + = __glibcxx_integral_traps; \ + static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \ + static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \ + = round_toward_zero; \ + }; \ + \ + template<> \ + struct numeric_limits \ + { \ + static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + min() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE); } \ + \ + UEXT \ + \ + static _GLIBCXX_USE_CONSTEXPR int digits \ + = BITSIZE; \ + static _GLIBCXX_USE_CONSTEXPR int digits10 \ + = BITSIZE * 643L / 2136; \ + static _GLIBCXX_USE_CONSTEXPR bool is_signed = false; \ + static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; \ + static _GLIBCXX_USE_CONSTEXPR int radix = 2; \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; \ + static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; \ + static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; \ + static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \ + = denorm_absent; \ + static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + infinity() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast(0); } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + quiet_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast(0); } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + signaling_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast(0); } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + denorm_min() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast(0); } \ + \ + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; \ + static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps; \ + static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \ + static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \ + = round_toward_zero; \ + }; #if __cplusplus >= 201103L - static constexpr __int128 - lowest() noexcept { return min(); } -#endif - static _GLIBCXX_USE_CONSTEXPR int digits - = __glibcxx_digits (__int128); - static _GLIBCXX_USE_CONSTEXPR int digits10 - = __glibcxx_digits10 (__int128); -#if __cplusplus >= 201103L +#define __INT_N_201103(TYPE) \ + static constexpr TYPE \ + lowest() noexcept { return min(); } \ static constexpr int max_digits10 = 0; -#endif - static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; - static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; - static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; - static _GLIBCXX_USE_CONSTEXPR int radix = 2; - - static _GLIBCXX_CONSTEXPR __int128 - epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_CONSTEXPR __int128 - round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; - static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; - static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; - static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; - - static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; - static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; - static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; - static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm - = denorm_absent; - static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; - - static _GLIBCXX_CONSTEXPR __int128 - infinity() _GLIBCXX_USE_NOEXCEPT - { return static_cast<__int128>(0); } - - static _GLIBCXX_CONSTEXPR __int128 - quiet_NaN() _GLIBCXX_USE_NOEXCEPT - { return static_cast<__int128>(0); } - - static _GLIBCXX_CONSTEXPR __int128 - signaling_NaN() _GLIBCXX_USE_NOEXCEPT - { return static_cast<__int128>(0); } - - static _GLIBCXX_CONSTEXPR __int128 - denorm_min() _GLIBCXX_USE_NOEXCEPT - { return static_cast<__int128>(0); } - - static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; - static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; - static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; - - static _GLIBCXX_USE_CONSTEXPR bool traps - = __glibcxx_integral_traps; - static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; - static _GLIBCXX_USE_CONSTEXPR float_round_style round_style - = round_toward_zero; - }; - - /// numeric_limits specialization. - template<> - struct numeric_limits - { - static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; - - static _GLIBCXX_CONSTEXPR unsigned __int128 - min() _GLIBCXX_USE_NOEXCEPT { return 0; } - static _GLIBCXX_CONSTEXPR unsigned __int128 - max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (unsigned __int128); } +#define __INT_N_U201103(TYPE) \ + static constexpr unsigned TYPE \ + lowest() noexcept { return min(); } \ + static constexpr int max_digits10 = 0; -#if __cplusplus >= 201103L - static constexpr unsigned __int128 - lowest() noexcept { return min(); } +#else +#define __INT_N_201103(TYPE) +#define __INT_N_U201103(TYPE) #endif - static _GLIBCXX_USE_CONSTEXPR int digits - = __glibcxx_digits (unsigned __int128); - static _GLIBCXX_USE_CONSTEXPR int digits10 - = __glibcxx_digits10 (unsigned __int128); -#if __cplusplus >= 201103L - static constexpr int max_digits10 = 0; +#ifdef __GLIBCXX_TYPE_INT_N_0 + __INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0, + __INT_N_201103 (__GLIBCXX_TYPE_INT_N_0), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_0)) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_1 + __INT_N (__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1, + __INT_N_201103 (__GLIBCXX_TYPE_INT_N_1), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_1)) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_2 + __INT_N (__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2, + __INT_N_201103 (__GLIBCXX_TYPE_INT_N_2), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_2)) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_3 + __INT_N (__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3, + __INT_N_201103 (__GLIBCXX_TYPE_INT_N_3), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_3)) #endif - static _GLIBCXX_USE_CONSTEXPR bool is_signed = false; - static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; - static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; - static _GLIBCXX_USE_CONSTEXPR int radix = 2; - - static _GLIBCXX_CONSTEXPR unsigned __int128 - epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; - static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; - static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; - static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; - - static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; - static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; - static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; - static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm - = denorm_absent; - static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; - - static _GLIBCXX_CONSTEXPR unsigned __int128 - infinity() _GLIBCXX_USE_NOEXCEPT - { return static_cast(0); } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - quiet_NaN() _GLIBCXX_USE_NOEXCEPT - { return static_cast(0); } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - signaling_NaN() _GLIBCXX_USE_NOEXCEPT - { return static_cast(0); } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - denorm_min() _GLIBCXX_USE_NOEXCEPT - { return static_cast(0); } - static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; - static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; - static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true; +#undef __INT_N +#undef __INT_N_201103 +#undef __INT_N_U201103 - static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps; - static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; - static _GLIBCXX_USE_CONSTEXPR float_round_style round_style - = round_toward_zero; - }; #endif /// numeric_limits specialization. diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index d776efeb68d..b92bbf09287 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -242,13 +242,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_integral_helper : public true_type { }; -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) + // Conditionalizing on __STRICT_ANSI__ here will break any port that + // uses one of these types for size_t. +#if defined(__GLIBCXX_TYPE_INT_N_0) template<> - struct __is_integral_helper<__int128> + struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0> : public true_type { }; template<> - struct __is_integral_helper + struct __is_integral_helper + : public true_type { }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + template<> + struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1> + : public true_type { }; + + template<> + struct __is_integral_helper + : public true_type { }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) + template<> + struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2> + : public true_type { }; + + template<> + struct __is_integral_helper + : public true_type { }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) + template<> + struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3> + : public true_type { }; + + template<> + struct __is_integral_helper : public true_type { }; #endif @@ -1661,10 +1690,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) +#if defined(__GLIBCXX_TYPE_INT_N_0) + template<> + struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> + { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + template<> + struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> + { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) template<> - struct __make_unsigned<__int128> - { typedef unsigned __int128 __type; }; + struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> + { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) + template<> + struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> + { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; }; #endif // Select between integral and enum: not possible to be both. @@ -1758,10 +1802,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) +#if defined(__GLIBCXX_TYPE_INT_N_0) + template<> + struct __make_signed + { typedef __GLIBCXX_TYPE_INT_N_0 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + template<> + struct __make_signed + { typedef __GLIBCXX_TYPE_INT_N_1 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) + template<> + struct __make_signed + { typedef __GLIBCXX_TYPE_INT_N_2 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) template<> - struct __make_signed - { typedef __int128 __type; }; + struct __make_signed + { typedef __GLIBCXX_TYPE_INT_N_3 __type; }; #endif // Select between integral and enum: not possible to be both. diff --git a/libstdc++-v3/src/c++11/limits.cc b/libstdc++-v3/src/c++11/limits.cc index 73335e7dc2b..5cb2b0edf0f 100644 --- a/libstdc++-v3/src/c++11/limits.cc +++ b/libstdc++-v3/src/c++11/limits.cc @@ -388,54 +388,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const bool numeric_limits::tinyness_before; const float_round_style numeric_limits::round_style; -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) - const bool numeric_limits<__int128>::is_specialized; - const int numeric_limits<__int128>::digits; - const int numeric_limits<__int128>::digits10; - const int numeric_limits<__int128>::max_digits10; - const bool numeric_limits<__int128>::is_signed; - const bool numeric_limits<__int128>::is_integer; - const bool numeric_limits<__int128>::is_exact; - const int numeric_limits<__int128>::radix; - const int numeric_limits<__int128>::min_exponent; - const int numeric_limits<__int128>::min_exponent10; - const int numeric_limits<__int128>::max_exponent; - const int numeric_limits<__int128>::max_exponent10; - const bool numeric_limits<__int128>::has_infinity; - const bool numeric_limits<__int128>::has_quiet_NaN; - const bool numeric_limits<__int128>::has_signaling_NaN; - const float_denorm_style numeric_limits<__int128>::has_denorm; - const bool numeric_limits<__int128>::has_denorm_loss; - const bool numeric_limits<__int128>::is_iec559; - const bool numeric_limits<__int128>::is_bounded; - const bool numeric_limits<__int128>::is_modulo; - const bool numeric_limits<__int128>::traps; - const bool numeric_limits<__int128>::tinyness_before; - const float_round_style numeric_limits<__int128>::round_style; - - const bool numeric_limits::is_specialized; - const int numeric_limits::digits; - const int numeric_limits::digits10; - const int numeric_limits::max_digits10; - const bool numeric_limits::is_signed; - const bool numeric_limits::is_integer; - const bool numeric_limits::is_exact; - const int numeric_limits::radix; - const int numeric_limits::min_exponent; - const int numeric_limits::min_exponent10; - const int numeric_limits::max_exponent; - const int numeric_limits::max_exponent10; - const bool numeric_limits::has_infinity; - const bool numeric_limits::has_quiet_NaN; - const bool numeric_limits::has_signaling_NaN; - const float_denorm_style numeric_limits::has_denorm; - const bool numeric_limits::has_denorm_loss; - const bool numeric_limits::is_iec559; - const bool numeric_limits::is_bounded; - const bool numeric_limits::is_modulo; - const bool numeric_limits::traps; - const bool numeric_limits::tinyness_before; - const float_round_style numeric_limits::round_style; +#define INT_N(__INT_N_TYPE) \ + const bool numeric_limits<__INT_N_TYPE>::is_specialized; \ + const int numeric_limits<__INT_N_TYPE>::digits; \ + const int numeric_limits<__INT_N_TYPE>::digits10; \ + const int numeric_limits<__INT_N_TYPE>::max_digits10; \ + const bool numeric_limits<__INT_N_TYPE>::is_signed; \ + const bool numeric_limits<__INT_N_TYPE>::is_integer; \ + const bool numeric_limits<__INT_N_TYPE>::is_exact; \ + const int numeric_limits<__INT_N_TYPE>::radix; \ + const int numeric_limits<__INT_N_TYPE>::min_exponent; \ + const int numeric_limits<__INT_N_TYPE>::min_exponent10; \ + const int numeric_limits<__INT_N_TYPE>::max_exponent; \ + const int numeric_limits<__INT_N_TYPE>::max_exponent10; \ + const bool numeric_limits<__INT_N_TYPE>::has_infinity; \ + const bool numeric_limits<__INT_N_TYPE>::has_quiet_NaN; \ + const bool numeric_limits<__INT_N_TYPE>::has_signaling_NaN; \ + const float_denorm_style numeric_limits<__INT_N_TYPE>::has_denorm; \ + const bool numeric_limits<__INT_N_TYPE>::has_denorm_loss; \ + const bool numeric_limits<__INT_N_TYPE>::is_iec559; \ + const bool numeric_limits<__INT_N_TYPE>::is_bounded; \ + const bool numeric_limits<__INT_N_TYPE>::is_modulo; \ + const bool numeric_limits<__INT_N_TYPE>::traps; \ + const bool numeric_limits<__INT_N_TYPE>::tinyness_before; \ + const float_round_style numeric_limits<__INT_N_TYPE>::round_style; \ + \ + const bool numeric_limits::is_specialized; \ + const int numeric_limits::digits; \ + const int numeric_limits::digits10; \ + const int numeric_limits::max_digits10; \ + const bool numeric_limits::is_signed; \ + const bool numeric_limits::is_integer; \ + const bool numeric_limits::is_exact; \ + const int numeric_limits::radix; \ + const int numeric_limits::min_exponent; \ + const int numeric_limits::min_exponent10; \ + const int numeric_limits::max_exponent; \ + const int numeric_limits::max_exponent10; \ + const bool numeric_limits::has_infinity; \ + const bool numeric_limits::has_quiet_NaN; \ + const bool numeric_limits::has_signaling_NaN; \ + const float_denorm_style numeric_limits::has_denorm; \ + const bool numeric_limits::has_denorm_loss; \ + const bool numeric_limits::is_iec559; \ + const bool numeric_limits::is_bounded; \ + const bool numeric_limits::is_modulo; \ + const bool numeric_limits::traps; \ + const bool numeric_limits::tinyness_before; \ + const float_round_style numeric_limits::round_style; + +#ifdef __GLIBCXX_TYPE_INT_N_0 + INT_N (__GLIBCXX_TYPE_INT_N_0) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_1 + INT_N (__GLIBCXX_TYPE_INT_N_1) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_2 + INT_N (__GLIBCXX_TYPE_INT_N_2) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_3 + INT_N (__GLIBCXX_TYPE_INT_N_3) #endif // float -- 2.30.2