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

Reply via email to