diff options
author | Geert Bosch <bosch@gcc.gnu.org> | 2002-03-08 21:11:04 +0100 |
---|---|---|
committer | Geert Bosch <bosch@gcc.gnu.org> | 2002-03-08 21:11:04 +0100 |
commit | 07fc65c47c45af6439208797e1ab26f7daedb666 (patch) | |
tree | b584a79288c93215b05fb451943291ccd039388b /gcc/ada/utils.c | |
parent | 24965e7a8ac518b99a3bd7ef5b2d8d88f96bf514 (diff) | |
download | gcc-07fc65c47c45af6439208797e1ab26f7daedb666.zip gcc-07fc65c47c45af6439208797e1ab26f7daedb666.tar.gz gcc-07fc65c47c45af6439208797e1ab26f7daedb666.tar.bz2 |
41intnam.ads, [...]: Merge in ACT changes.
* 41intnam.ads, 42intnam.ads, 4aintnam.ads, 4cintnam.ads,
4dintnam.ads, 4gintnam.ads, 4hintnam.ads, 4lintnam.ads,
4mintnam.ads, 4pintnam.ads, 4rintnam.ads, 4sintnam.ads,
4uintnam.ads, 4vcalend.adb, 4zintnam.ads, 52system.ads,
5amastop.adb, 5asystem.ads, 5ataprop.adb, 5atpopsp.adb,
5avxwork.ads, 5bosinte.adb, 5bsystem.ads, 5esystem.ads,
5fsystem.ads, 5ftaprop.adb, 5ginterr.adb, 5gmastop.adb,
5gsystem.ads, 5gtaprop.adb, 5gtasinf.adb, 5gtasinf.ads,
5hparame.ads, 5hsystem.ads, 5htaprop.adb, 5htraceb.adb,
5itaprop.adb, 5ksystem.ads, 5kvxwork.ads, 5lintman.adb,
5lsystem.ads, 5mvxwork.ads, 5ninmaop.adb, 5nosinte.ads,
5ntaprop.adb, 5ointerr.adb, 5omastop.adb, 5oosinte.adb,
5osystem.ads, 5otaprop.adb, 5otaspri.ads, 5pvxwork.ads,
5qtaprop.adb, 5sintman.adb, 5ssystem.ads, 5staprop.adb,
5stpopse.adb, 5svxwork.ads, 5tosinte.ads, 5uintman.adb,
5vasthan.adb, 5vinmaop.adb, 5vinterr.adb, 5vintman.adb,
5vmastop.adb, 5vparame.ads, 5vsystem.ads, 5vtaprop.adb,
5vtpopde.adb, 5wmemory.adb, 5wsystem.ads, 5wtaprop.adb,
5ysystem.ads, 5zinterr.adb, 5zintman.adb, 5zosinte.adb,
5zosinte.ads, 5zsystem.ads, 5ztaprop.adb, 6vcpp.adb, 6vcstrea.adb,
7sintman.adb, 7staprop.adb, 7stpopsp.adb, 9drpc.adb,
Make-lang.in, Makefile.in, a-caldel.adb, a-comlin.ads,
a-dynpri.adb, a-except.adb, a-except.ads, a-finali.adb,
a-ncelfu.ads, a-reatim.adb, a-retide.adb, a-stream.ads,
a-ststio.adb, a-ststio.ads, a-stwifi.adb, a-tags.adb, a-tasatt.adb,
a-textio.adb, a-tideau.adb, a-tiflau.adb, a-tigeau.adb,
a-tigeau.ads, a-tiinau.adb, a-timoau.adb, a-witeio.adb,
a-wtdeau.adb, a-wtenau.adb, a-wtflau.adb, a-wtgeau.adb,
a-wtgeau.ads, a-wtinau.adb, a-wtmoau.adb, ada-tree.def, ada-tree.h,
adaint.c, adaint.h, ali-util.adb, ali.adb, ali.ads, atree.adb,
atree.ads, atree.h, back_end.adb, bcheck.adb, bindgen.adb,
bindusg.adb, checks.adb, comperr.adb, config-lang.in, csets.adb,
csets.ads, cstand.adb, cstreams.c, debug.adb, debug.ads, decl.c,
einfo.adb, einfo.ads, einfo.h, elists.h, errout.adb, errout.ads,
eval_fat.adb, exp_aggr.adb, exp_attr.adb, exp_ch11.adb,
exp_ch12.adb, exp_ch13.adb, exp_ch2.adb, exp_ch3.adb, exp_ch3.ads,
exp_ch4.adb, exp_ch5.adb, exp_ch6.adb, exp_ch7.adb, exp_ch7.ads,
exp_ch9.adb, exp_ch9.ads, exp_dbug.adb, exp_dbug.ads, exp_disp.ads,
exp_dist.adb, exp_fixd.adb, exp_intr.adb, exp_pakd.adb,
exp_prag.adb, exp_strm.adb, exp_util.adb, exp_util.ads,
expander.adb, expect.c, fe.h, fmap.adb, fmap.ads, fname-uf.adb,
freeze.adb, frontend.adb, g-awk.adb, g-cgideb.adb, g-comlin.adb,
g-comlin.ads, g-debpoo.adb, g-dirope.adb, g-dirope.ads,
g-dyntab.adb, g-expect.adb, g-expect.ads, g-io.ads, g-io_aux.adb,
g-io_aux.ads, g-locfil.adb, g-locfil.ads, g-os_lib.adb,
g-os_lib.ads, g-regexp.adb, g-regpat.adb, g-socket.adb,
g-socket.ads, g-spipat.adb, g-table.adb, g-trasym.adb,
g-trasym.ads, gigi.h, gmem.c, gnat1drv.adb, gnatbind.adb, gnatbl.c,
gnatchop.adb, gnatcmd.adb, gnatdll.adb, gnatfind.adb, gnatlbr.adb,
gnatlink.adb, gnatls.adb, gnatmem.adb, gnatprep.adb, gnatvsn.ads,
gnatxref.adb, hlo.adb, hostparm.ads, i-cobol.adb, i-cpp.adb,
i-cstrea.ads, i-cstrin.adb, i-pacdec.adb, i-vxwork.ads,
impunit.adb, init.c, inline.adb, io-aux.c, layout.adb, lib-load.adb,
lib-util.adb, lib-writ.adb, lib-writ.ads, lib-xref.adb,
lib-xref.ads, lib.adb, lib.ads, make.adb, makeusg.adb, mdll.adb,
memroot.adb, misc.c, mlib-tgt.adb, mlib-utl.adb, mlib-utl.ads,
mlib.adb, namet.adb, namet.ads, namet.h, nlists.h, nmake.adb,
nmake.ads, nmake.adt, opt.adb, opt.ads, osint.adb, osint.ads,
output.adb, output.ads, par-ch2.adb, par-ch3.adb, par-ch5.adb,
par-prag.adb, par-tchk.adb, par-util.adb, par.adb, prj-attr.adb,
prj-dect.adb, prj-env.adb, prj-env.ads, prj-nmsc.adb, prj-part.adb,
prj-proc.adb, prj-strt.adb, prj-tree.adb, prj-tree.ads, prj.adb,
prj.ads, raise.c, raise.h, repinfo.adb, restrict.adb, restrict.ads,
rident.ads, rtsfind.adb, rtsfind.ads, s-arit64.adb, s-asthan.adb,
s-atacco.adb, s-atacco.ads, s-auxdec.adb, s-crc32.adb, s-crc32.ads,
s-direio.adb, s-fatgen.adb, s-fileio.adb, s-finimp.adb,
s-gloloc.adb, s-gloloc.ads, s-interr.adb, s-mastop.adb,
s-mastop.ads, s-memory.adb, s-parame.ads, s-parint.adb,
s-pooglo.adb, s-pooloc.adb, s-rpc.adb, s-secsta.adb, s-sequio.adb,
s-shasto.adb, s-soflin.adb, s-soflin.ads, s-stache.adb,
s-taasde.adb, s-taasde.ads, s-tadeca.adb, s-tadeca.ads,
s-tadert.adb, s-tadert.ads, s-taenca.adb, s-taenca.ads,
s-taprob.adb, s-taprop.ads, s-tarest.adb, s-tasdeb.adb,
s-tasini.adb, s-tasini.ads, s-taskin.adb, s-taskin.ads,
s-tasque.adb, s-tasque.ads, s-tasren.adb, s-tasren.ads,
s-tassta.adb, s-tasuti.adb, s-tasuti.ads, s-tataat.adb,
s-tataat.ads, s-tpoben.adb, s-tpoben.ads, s-tpobop.adb,
s-tposen.adb, s-tposen.ads, s-traceb.adb, s-traceb.ads,
s-unstyp.ads, s-widenu.adb, scn-nlit.adb, scn.adb, sem.adb,
sem_aggr.adb, sem_attr.adb, sem_attr.ads, sem_case.adb,
sem_ch10.adb, sem_ch11.adb, sem_ch11.ads, sem_ch12.adb,
sem_ch13.adb, sem_ch13.ads, sem_ch2.adb, sem_ch3.adb, sem_ch3.ads,
sem_ch4.adb, sem_ch5.adb, sem_ch6.adb, sem_ch6.ads, sem_ch7.adb,
sem_ch8.adb, sem_ch8.ads, sem_ch9.adb, sem_disp.adb, sem_dist.adb,
sem_elab.adb, sem_elim.adb, sem_elim.ads, sem_eval.adb,
sem_intr.adb, sem_mech.adb, sem_prag.adb, sem_res.adb,
sem_type.adb, sem_util.adb, sem_util.ads, sem_vfpt.adb,
sem_warn.adb, sinfo.adb, sinfo.ads, sinfo.h, sinput-l.adb,
sinput-l.ads, sinput.adb, sinput.ads, snames.adb, snames.ads,
snames.h, sprint.adb, sprint.ads, stringt.adb, stringt.ads,
stringt.h, style.adb, switch.adb, switch.ads, sysdep.c, system.ads,
table.adb, targparm.adb, targparm.ads, targtyps.c, tbuild.adb,
tbuild.ads, tracebak.c, trans.c, tree_gen.adb, tree_io.adb,
treepr.adb, treepr.ads, treeprs.ads, treeprs.adt, ttypes.ads,
types.adb, types.ads, types.h, uintp.ads, urealp.ads, usage.adb,
utils.c, utils2.c, validsw.adb, xnmake.adb, xr_tabls.adb,
xr_tabls.ads, xref_lib.adb, xref_lib.ads : Merge in ACT changes.
* 1ssecsta.adb, 1ssecsta.ads, a-chlat9.ads, a-cwila9.ads,
g-enblsp.adb, g-md5.adb, g-md5.ads, gnatname.adb, gnatname.ads,
mkdir.c, osint-b.adb, osint-b.ads, osint-c.adb, osint-c.ads,
osint-l.adb, osint-l.ads, osint-m.adb, osint-m.ads : New files
* 3lsoccon.ads, 5qparame.ads, 5qvxwork.ads, 5smastop.adb,
5zparame.ads, gnatmain.adb, gnatmain.ads, gnatpsys.adb : Removed
* mdllfile.adb, mdllfile.ads, mdlltool.adb, mdlltool.ads : Renamed
to mdll-fil.ad[bs] and mdll-util.ad[bs]
* mdll-fil.adb, mdll-fil.ads, mdll-utl.adb, mdll-utl.ads : Renamed
from mdllfile.ad[bs] and mdlltool.ad[bs]
From-SVN: r50451
Diffstat (limited to 'gcc/ada/utils.c')
-rw-r--r-- | gcc/ada/utils.c | 232 |
1 files changed, 123 insertions, 109 deletions
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c index 224f431..c606c20 100644 --- a/gcc/ada/utils.c +++ b/gcc/ada/utils.c @@ -6,9 +6,9 @@ * * * C Implementation File * * * - * $Revision: 1.8 $ + * $Revision$ * * - * Copyright (C) 1992-2001, Free Software Foundation, Inc. * + * Copyright (C) 1992-2002, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -61,9 +61,12 @@ /* If nonzero, pretend we are allocating at global level. */ int force_global; -/* Global Variables for the various types we create. */ +/* Tree nodes for the various types and decls we create. */ tree gnat_std_decls[(int) ADT_LAST]; +/* Functions to call for each of the possible raise reasons. */ +tree gnat_raise_decls[(int) LAST_REASON_CODE + 1]; + /* Associates a GNAT tree node to a GCC tree node. It is used in `save_gnu_tree', `get_gnu_tree' and `present_gnu_tree'. See documentation of `save_gnu_tree' for more info. */ @@ -131,7 +134,6 @@ static struct binding_level *global_binding_level; /* Binding level structures are initialized by copying this one. */ static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL}; - static tree merge_sizes PARAMS ((tree, tree, tree, int, int)); static tree compute_related_constant PARAMS ((tree, tree)); static tree split_plus PARAMS ((tree, tree *)); @@ -141,8 +143,8 @@ static tree convert_to_fat_pointer PARAMS ((tree, tree)); static tree convert_to_thin_pointer PARAMS ((tree, tree)); static tree make_descriptor_field PARAMS ((const char *,tree, tree, tree)); -static void mark_binding_level PARAMS((PTR)); -static void mark_e_stack PARAMS((PTR)); +static void mark_binding_level PARAMS ((PTR)); +static void mark_e_stack PARAMS ((PTR)); /* Initialize the association of GNAT nodes to GCC trees. */ @@ -155,9 +157,7 @@ init_gnat_to_gnu () ggc_add_tree_root (associate_gnat_to_gnu, max_gnat_nodes); for (gnat_node = 0; gnat_node < max_gnat_nodes; gnat_node++) - associate_gnat_to_gnu [gnat_node] = NULL_TREE; - - associate_gnat_to_gnu -= First_Node_Id; + associate_gnat_to_gnu[gnat_node] = NULL_TREE; pending_elaborations = build_tree_list (NULL_TREE, NULL_TREE); ggc_add_tree_root (&pending_elaborations, 1); @@ -184,11 +184,11 @@ save_gnu_tree (gnat_entity, gnu_decl, no_check) int no_check; { if (gnu_decl - && (associate_gnat_to_gnu [gnat_entity] + && (associate_gnat_to_gnu[gnat_entity - First_Node_Id] || (! no_check && ! DECL_P (gnu_decl)))) gigi_abort (401); - associate_gnat_to_gnu [gnat_entity] = gnu_decl; + associate_gnat_to_gnu[gnat_entity - First_Node_Id] = gnu_decl; } /* GNAT_ENTITY is a GNAT tree node for a defining identifier. @@ -202,10 +202,10 @@ tree get_gnu_tree (gnat_entity) Entity_Id gnat_entity; { - if (! associate_gnat_to_gnu [gnat_entity]) + if (! associate_gnat_to_gnu[gnat_entity - First_Node_Id]) gigi_abort (402); - return associate_gnat_to_gnu [gnat_entity]; + return associate_gnat_to_gnu[gnat_entity - First_Node_Id]; } /* Return nonzero if a GCC tree has been associated with GNAT_ENTITY. */ @@ -214,7 +214,7 @@ int present_gnu_tree (gnat_entity) Entity_Id gnat_entity; { - return (associate_gnat_to_gnu [gnat_entity] != NULL_TREE); + return (associate_gnat_to_gnu[gnat_entity - First_Node_Id] != NULL_TREE); } @@ -523,7 +523,8 @@ void init_gigi_decls (long_long_float_type, exception_type) tree long_long_float_type, exception_type; { - tree endlink; + tree endlink, decl; + unsigned int i; /* Set the types that GCC and Gigi use from the front end. We would like to do this for char_type_node, but it needs to correspond to the C @@ -607,7 +608,7 @@ init_gigi_decls (long_long_float_type, exception_type) build_function_type (build_pointer_type (except_type_node), NULL_TREE), NULL_TREE, 0, 1, 1, 0); - /* Function that raise exceptions. */ + /* Functions that raise exceptions. */ raise_nodefer_decl = create_subprog_decl (get_identifier ("__gnat_raise_nodefer_with_msg"), NULL_TREE, @@ -617,68 +618,61 @@ init_gigi_decls (long_long_float_type, exception_type) endlink)), NULL_TREE, 0, 1, 1, 0); - - /* __gnat_raise_constraint_error takes a string, an integer and never - returns. */ - raise_constraint_error_decl - = create_subprog_decl - (get_identifier ("__gnat_raise_constraint_error"), NULL_TREE, - build_function_type (void_type_node, - tree_cons (NULL_TREE, - build_pointer_type (char_type_node), - tree_cons (NULL_TREE, - integer_type_node, - endlink))), - NULL_TREE, 0, 1, 1, 0); - - /* Likewise for __gnat_raise_program_error. */ - raise_program_error_decl - = create_subprog_decl - (get_identifier ("__gnat_raise_program_error"), NULL_TREE, - build_function_type (void_type_node, - tree_cons (NULL_TREE, - build_pointer_type (char_type_node), - tree_cons (NULL_TREE, - integer_type_node, - endlink))), - NULL_TREE, 0, 1, 1, 0); - - /* Likewise for __gnat_raise_storage_error. */ - raise_storage_error_decl - = create_subprog_decl - (get_identifier ("__gnat_raise_storage_error"), NULL_TREE, - build_function_type (void_type_node, - tree_cons (NULL_TREE, - build_pointer_type (char_type_node), - tree_cons (NULL_TREE, - integer_type_node, - endlink))), - NULL_TREE, 0, 1, 1, 0); + /* If in no exception handlers mode, all raise statements are redirected to + __gnat_last_chance_handler. No need to redefine raise_nodefer_decl, since + this procedure will never be called in this mode. */ + if (No_Exception_Handlers_Set ()) + { + decl + = create_subprog_decl + (get_identifier ("__gnat_last_chance_handler"), NULL_TREE, + build_function_type (void_type_node, + tree_cons (NULL_TREE, + build_pointer_type (char_type_node), + tree_cons (NULL_TREE, + integer_type_node, + endlink))), + NULL_TREE, 0, 1, 1, 0); + + for (i = 0; i < sizeof gnat_raise_decls / sizeof gnat_raise_decls[0]; + i++) + gnat_raise_decls[i] = decl; + } + else + /* Otherwise, make one decl for each exception reason. */ + for (i = 0; i < sizeof gnat_raise_decls / sizeof gnat_raise_decls[0]; i++) + { + char name[17]; + + sprintf (name, "__gnat_rcheck_%.2d", i); + gnat_raise_decls[i] + = create_subprog_decl + (get_identifier (name), NULL_TREE, + build_function_type (void_type_node, + tree_cons (NULL_TREE, + build_pointer_type + (char_type_node), + tree_cons (NULL_TREE, + integer_type_node, + endlink))), + NULL_TREE, 0, 1, 1, 0); + } /* Indicate that these never return. */ - TREE_THIS_VOLATILE (raise_nodefer_decl) = 1; - TREE_THIS_VOLATILE (raise_constraint_error_decl) = 1; - TREE_THIS_VOLATILE (raise_program_error_decl) = 1; - TREE_THIS_VOLATILE (raise_storage_error_decl) = 1; - TREE_SIDE_EFFECTS (raise_nodefer_decl) = 1; - TREE_SIDE_EFFECTS (raise_constraint_error_decl) = 1; - TREE_SIDE_EFFECTS (raise_program_error_decl) = 1; - TREE_SIDE_EFFECTS (raise_storage_error_decl) = 1; - TREE_TYPE (raise_nodefer_decl) = build_qualified_type (TREE_TYPE (raise_nodefer_decl), TYPE_QUAL_VOLATILE); - TREE_TYPE (raise_constraint_error_decl) - = build_qualified_type (TREE_TYPE (raise_constraint_error_decl), - TYPE_QUAL_VOLATILE); - TREE_TYPE (raise_program_error_decl) - = build_qualified_type (TREE_TYPE (raise_program_error_decl), - TYPE_QUAL_VOLATILE); - TREE_TYPE (raise_storage_error_decl) - = build_qualified_type (TREE_TYPE (raise_storage_error_decl), - TYPE_QUAL_VOLATILE); + + for (i = 0; i < sizeof gnat_raise_decls / sizeof gnat_raise_decls[0]; i++) + { + TREE_THIS_VOLATILE (gnat_raise_decls[i]) = 1; + TREE_SIDE_EFFECTS (gnat_raise_decls[i]) = 1; + TREE_TYPE (gnat_raise_decls[i]) + = build_qualified_type (TREE_TYPE (gnat_raise_decls[i]), + TYPE_QUAL_VOLATILE); + } /* setjmp returns an integer and has one operand, which is a pointer to a jmpbuf. */ @@ -692,7 +686,10 @@ init_gigi_decls (long_long_float_type, exception_type) DECL_BUILT_IN_CLASS (setjmp_decl) = BUILT_IN_NORMAL; DECL_FUNCTION_CODE (setjmp_decl) = BUILT_IN_SETJMP; + main_identifier_node = get_identifier ("main"); + ggc_add_tree_root (gnat_std_decls, ARRAY_SIZE (gnat_std_decls)); + ggc_add_tree_root (gnat_raise_decls, ARRAY_SIZE (gnat_raise_decls)); } /* This routine is called in tree.c to print an error message for invalid use @@ -737,6 +734,7 @@ finish_record_type (record_type, fieldlist, has_rep, defer_debug) tree ada_size = bitsize_zero_node; tree size = bitsize_zero_node; tree size_unit = size_zero_node; + int var_size = 0; tree field; TYPE_FIELDS (record_type) = fieldlist; @@ -792,6 +790,15 @@ finish_record_type (record_type, fieldlist, has_rep, defer_debug) tree this_size_unit = DECL_SIZE_UNIT (field); tree this_ada_size = DECL_SIZE (field); + /* We need to make an XVE/XVU record if any field has variable size, + whether or not the record does. For example, if we have an union, + it may be that all fields, rounded up to the alignment, have the + same size, in which case we'll use that size. But the debug + output routines (except Dwarf2) won't be able to output the fields, + so we need to make the special record. */ + if (TREE_CODE (this_size) != INTEGER_CST) + var_size = 1; + if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE) && ! TYPE_IS_FAT_POINTER_P (type) @@ -890,7 +897,7 @@ finish_record_type (record_type, fieldlist, has_rep, defer_debug) debugger knows it is and make a new, parallel, record that tells the debugger how the record is laid out. See exp_dbug.ads. */ - if (TREE_CODE (TYPE_SIZE (record_type)) != INTEGER_CST) + if (var_size) { tree new_record_type = make_node (TREE_CODE (record_type) == QUAL_UNION_TYPE @@ -972,7 +979,7 @@ finish_record_type (record_type, fieldlist, has_rep, defer_debug) /* See if this type is variable-size and make a new type and indicate the indirection if so. */ - if (TREE_CODE (TYPE_SIZE (field_type)) != INTEGER_CST) + if (TREE_CODE (DECL_SIZE (old_field)) != INTEGER_CST) { field_type = build_pointer_type (field_type); var = 1; @@ -994,7 +1001,7 @@ finish_record_type (record_type, fieldlist, has_rep, defer_debug) new_field = create_field_decl (field_name, field_type, new_record_type, 0, - TYPE_SIZE (field_type), pos, 0); + DECL_SIZE (old_field), pos, 0); TREE_CHAIN (new_field) = TYPE_FIELDS (new_record_type); TYPE_FIELDS (new_record_type) = new_field; @@ -1007,7 +1014,7 @@ finish_record_type (record_type, fieldlist, has_rep, defer_debug) (TREE_CODE (TREE_TYPE (old_field)) == QUAL_UNION_TYPE) ? bitsize_zero_node - : TYPE_SIZE (TREE_TYPE (old_field))); + : DECL_SIZE (old_field)); } TYPE_FIELDS (new_record_type) @@ -1484,14 +1491,21 @@ create_field_decl (field_name, field_type, record_type, packed, size, pos, known_align = TYPE_ALIGN (record_type); layout_decl (field_decl, known_align); - SET_DECL_OFFSET_ALIGN (field_decl, BIGGEST_ALIGNMENT); + SET_DECL_OFFSET_ALIGN (field_decl, + host_integerp (pos, 1) ? BIGGEST_ALIGNMENT + : BITS_PER_UNIT); pos_from_bit (&DECL_FIELD_OFFSET (field_decl), &DECL_FIELD_BIT_OFFSET (field_decl), - BIGGEST_ALIGNMENT, pos); + DECL_OFFSET_ALIGN (field_decl), pos); DECL_HAS_REP_P (field_decl) = 1; } + /* If the field type is passed by reference, we will have pointers to the + field, so it is addressable. */ + if (must_pass_by_ref (field_type) || default_pass_by_ref (field_type)) + addressable = 1; + /* Mark the decl as nonaddressable if it either is indicated so semantically or if it is a bit field. */ DECL_NONADDRESSABLE_P (field_decl) @@ -1714,8 +1728,8 @@ create_label_decl (label_name) node), PARAM_DECL_LIST is the list of the subprogram arguments (a list of PARM_DECL nodes chained through the TREE_CHAIN field). - INLINE_FLAG, PUBLIC_FLAG, and EXTERN_FLAG are used to set the appropriate - fields in the FUNCTION_DECL. */ + INLINE_FLAG, PUBLIC_FLAG, EXTERN_FLAG, and ATTR_LIST are used to set the + appropriate fields in the FUNCTION_DECL. */ tree create_subprog_decl (subprog_name, asm_name, subprog_type, param_decl_list, @@ -1821,10 +1835,16 @@ begin_subprog_body (subprog_decl) /* Store back the PARM_DECL nodes. They appear in the right order. */ DECL_ARGUMENTS (subprog_decl) = getdecls (); - init_function_start (subprog_decl, input_filename, lineno); + init_function_start (subprog_decl, input_filename, lineno); expand_function_start (subprog_decl, 0); -} + /* If this function is `main', emit a call to `__main' + to run global initializers, etc. */ + if (DECL_ASSEMBLER_NAME (subprog_decl) != 0 + && MAIN_NAME_P (DECL_ASSEMBLER_NAME (subprog_decl)) + && DECL_CONTEXT (subprog_decl) == NULL_TREE) + expand_main_function (); +} /* Finish the definition of the current subprogram and compile it all the way to assembler language output. */ @@ -2823,7 +2843,7 @@ convert (type, expr) /* If we previously converted from another type and our type is of variable size, remove the conversion to avoid the need for variable-size temporaries. */ - if (TREE_CODE (expr) == UNCHECKED_CONVERT_EXPR + if (TREE_CODE (expr) == VIEW_CONVERT_EXPR && ! TREE_CONSTANT (TYPE_SIZE (type))) expr = TREE_OPERAND (expr, 0); @@ -2946,7 +2966,7 @@ convert (type, expr) ecode = TREE_CODE (etype); break; - case UNCHECKED_CONVERT_EXPR: + case VIEW_CONVERT_EXPR: if (AGGREGATE_TYPE_P (type) && AGGREGATE_TYPE_P (etype) && ! TYPE_FAT_POINTER_P (type) && ! TYPE_FAT_POINTER_P (etype)) return convert (type, TREE_OPERAND (expr, 0)); @@ -3104,29 +3124,33 @@ convert (type, expr) } /* Remove all conversions that are done in EXP. This includes converting - from a padded type or converting to a left-justified modular type. */ + from a padded type or to a left-justified modular type. If TRUE_ADDRESS + is nonzero, always return the address of the containing object even if + the address is not bit-aligned. */ tree -remove_conversions (exp) +remove_conversions (exp, true_address) tree exp; + int true_address; { switch (TREE_CODE (exp)) { case CONSTRUCTOR: - if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE + if (true_address + && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE && TYPE_LEFT_JUSTIFIED_MODULAR_P (TREE_TYPE (exp))) - return remove_conversions (TREE_VALUE (CONSTRUCTOR_ELTS (exp))); + return remove_conversions (TREE_VALUE (CONSTRUCTOR_ELTS (exp)), 1); break; case COMPONENT_REF: if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == RECORD_TYPE && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (exp, 0)))) - return remove_conversions (TREE_OPERAND (exp, 0)); + return remove_conversions (TREE_OPERAND (exp, 0), true_address); break; - case UNCHECKED_CONVERT_EXPR: - case NOP_EXPR: case CONVERT_EXPR: - return remove_conversions (TREE_OPERAND (exp, 0)); + case VIEW_CONVERT_EXPR: case NON_LVALUE_EXPR: + case NOP_EXPR: case CONVERT_EXPR: case GNAT_NOP_EXPR: + return remove_conversions (TREE_OPERAND (exp, 0), true_address); default: break; @@ -3297,26 +3321,16 @@ unchecked_convert (type, expr) else if (TREE_CODE (etype) == UNCONSTRAINED_ARRAY_TYPE && TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE) expr = build_unary_op (INDIRECT_REF, NULL_TREE, - build1 (UNCHECKED_CONVERT_EXPR, TREE_TYPE (type), + build1 (VIEW_CONVERT_EXPR, TREE_TYPE (type), build_unary_op (ADDR_EXPR, NULL_TREE, expr))); - - /* If both types are aggregates with the same mode and alignment (except - if the result is a UNION_TYPE), we can do this as a normal conversion. */ - else if (AGGREGATE_TYPE_P (type) && AGGREGATE_TYPE_P (etype) - && TREE_CODE (type) != UNION_TYPE - && TYPE_ALIGN (type) == TYPE_ALIGN (etype) - && TYPE_MODE (type) == TYPE_MODE (etype)) - expr = build1 (CONVERT_EXPR, type, expr); - else { expr = maybe_unconstrained_array (expr); etype = TREE_TYPE (expr); - expr = build1 (UNCHECKED_CONVERT_EXPR, type, expr); + expr = build1 (VIEW_CONVERT_EXPR, type, expr); } - /* If the result is an integral type whose size is not equal to the size of the underlying machine type, sign- or zero-extend the result. We need not do this in the case where the input is @@ -3352,16 +3366,16 @@ unchecked_convert (type, expr) } /* An unchecked conversion should never raise Constraint_Error. The code - below assumes that GCC's conversion routines overflow the same - way that the underlying hardware does. This is probably true. In - the rare case when it isn't, we can rely on the fact that such - conversions are erroneous anyway. */ + below assumes that GCC's conversion routines overflow the same way that + the underlying hardware does. This is probably true. In the rare case + when it is false, we can rely on the fact that such conversions are + erroneous anyway. */ if (TREE_CODE (expr) == INTEGER_CST) TREE_OVERFLOW (expr) = TREE_CONSTANT_OVERFLOW (expr) = 0; - /* If the sizes of the types differ and this is an UNCHECKED_CONVERT_EXPR, + /* If the sizes of the types differ and this is an VIEW_CONVERT_EXPR, show no longer constant. */ - if (TREE_CODE (expr) == UNCHECKED_CONVERT_EXPR + if (TREE_CODE (expr) == VIEW_CONVERT_EXPR && ! operand_equal_p (TYPE_SIZE_UNIT (type), TYPE_SIZE_UNIT (etype), 1)) TREE_CONSTANT (expr) = 0; |