> 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;" ?