> Everything handling __int128 would be updated to work with a > target-determined set of types instead. > > Preferably, the number of such keywords would be arbitrary (so I suppose > there would be a single RID_INTN for them) - that seems cleaner than the > system for address space keywords with a fixed block from RID_ADDR_SPACE_0 > to RID_ADDR_SPACE_15.
I did a scan through the gcc source tree trying to track down all the implications of this, and there were a lot of them, and not just the RID_* stuff. There's also the integer_types[] array (indexed by itk_*, which is its own mess) and c_common_reswords[] array, for example. I think it might not be possible to have one RID_* map to multiple actual keywords, as there are few cases that need to know *which* intN is used *and* have access to the original string of the token, and many cases where code assumes a 1:1 relation between RID_*, a type, and a keyword string. IMHO the key design choices come down to: * Do we change a few global const arrays to be dynamic arrays? * We need to consider that "position in array" is no longer a suitable sort key for these arrays. itk_* comes to mind here, but RID_* are abused sometimes too. (note: I've seen this before, where PSImode isn't included in "find smallest mode" logic, for example, because it's no in the array in the same place as SImode) * Need to dynamically map keywords/bitsizes/tokens to types in all the cases where we explicitly check for int128. Some of these places have explicit "check types in the right order" logic hard-coded that may need to be changed to a data-search logic. * The C++ mangler needs to know what to do with these new types. I'll attach my notes from the scan for reference... ---------------------------------------- Search for in128 ... Search for c_common_reswords ... Search for itk_ ... --- . --- tree-core.h enum integer_type_kind is used to map all integer types "in order" so we need an alternate way to map them. Currently hard-codes the itk_int128 types. tree.h defines int128_unsigned_type_node and int128_integer_type_node uses itk_int128 and itk_unsigned_int128 - int128_*_type_node is an [itk_*] array reference. builtin-types.def defines BT_INT182 but nothing uses it yet. gimple.c gimple_signed_or_unsigned_type maps types to their signed or unsigned variant. Two cases: one checks for int128 explicitly, the other checks for compatibility with int128. tree.c make_or_reuse_type maps size/signed to a int128_integer_type_node etc. build_common_tree_nodes makes int128_*_type_node if the target supports TImode. tree-streamer.c preload_common_nodes() records one node per itk_* --- LTO --- lto.c read_cgraph_and_symbols() reads one node per integer_types[itk_*] --- C-FAMILY --- c-lex.c intepret_integer scans itk_* to find the best (smallest) type for integers. narrowest_unsigned_type assumes integer_types[itk_*] in bit-size order, and assumes [N*2] is signed/unsigned pairs. narrowest_signed_type: same. c-cppbuiltin.c __SIZEOF_INTn__ for each intN c-pretty-print.c prints I128 suffix for int128-sized integer literals. c-common.c int128_* has an entry in c_global_trees[] c_common_reswords[] has an entry for __int128 -> RID_INT128 c_common_type_for_size maps int:128 to int128_*_type_node c_common_type_for_mode: same. c_common_signed_or_unsigned_type - checks for int128 types. same as igmple_signed_or_unsigned_type?() c_build_bitfield_integer_type assigns int128_*_type_node for :128 fields. c_common_nodes_and_builtins maps int128_*_type_node to RID_INT128 and "__int128". Also maps to decl __int128_t keyword_begins_type_specifier() checks for RID_INT128 --- C --- c-tree.h adds cts_int128 to c_typespec_keyword[] c-parser.c c_parse_init() reads c_common_reswords[] which has __int128, maps one id to each RID_* code. c_token_starts_typename() checks for RID_INT128 c_token_starts_declspecs() checks for RID_INT128 c_parser_declspecs() checks for RID_INT128 c_parser_attribute_any_word() checks for RID_INT128 c_parser_objc_selector() checks for RID_INT128 c-decl.c error for "long __int128" etc throughout declspecs_add_type() checks for RID_INT128 finish_declspecs() checks for cts_int128 --- FORTRAN --- ico-c-binding.def maps int128_t to c_int128_t via get_int_kind_from_width( --- C++ --- class.c layout_class_types uses itk_* to find the best (smallest) integer type for overlarge bitfields. lex.c init_reswords() reads c_common_reswords[], which includes __int128 rtti.c emit_support_tinfos has a dummy list of types fundamentals[] that hardcodes int128_*_type_node in it. decl.c checks for __int128 in declspecs to report if it's not supported. finish_enum_value_list() uses itk_* to find the right type for enums. build_enumerator() also. parser.c all RID_INTN need to be in cp_lexer_next_token_is_decl_specifier_keyword() (simple true/false) cp_parser_simple_type_specifier uses __intN as type selector in a decl. (has token->keyword available, token->u.value is a tree?) mangle.c 'n', /* itk_int128 */ 'o', /* itk_unsigned_int128 */ typeck.c cp_common_type() needs to know about intN compatibility with other integer types. cp-tree.h cp_decl_specifier_seq needs a bool for each intN specified. (else, what about "__int8 __int16 foo;" ?