00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #include "system.h"
00029 #ifdef SGI_MONGOOSE
00030
00031 #include "rtl.h"
00032 #endif
00033 #include "tree.h"
00034 #ifndef SGI_MONGOOSE
00035 #include "rtl.h"
00036 #endif
00037 #include "tm_p.h"
00038 #include "flags.h"
00039 #include "function.h"
00040 #include "expr.h"
00041 #include "toplev.h"
00042 #include "ggc.h"
00043 #include "target.h"
00044 #include "langhooks.h"
00045
00046
00047 static int sizetype_set;
00048
00049
00050
00051 static tree early_type_list;
00052
00053
00054
00055 tree sizetype_tab[(int) TYPE_KIND_LAST];
00056
00057
00058
00059 unsigned int maximum_field_alignment;
00060
00061
00062
00063 unsigned int set_alignment = 0;
00064
00065
00066
00067
00068 static int reference_types_internal = 0;
00069
00070 static void finalize_record_size PARAMS ((record_layout_info));
00071 static void finalize_type_size PARAMS ((tree));
00072 static void place_union_field PARAMS ((record_layout_info, tree));
00073 static unsigned int update_alignment_for_field
00074 PARAMS ((record_layout_info, tree,
00075 unsigned int));
00076 extern void debug_rli PARAMS ((record_layout_info));
00077
00078
00079
00080 static GTY(()) tree pending_sizes;
00081
00082
00083
00084
00085 int immediate_size_expand;
00086
00087
00088
00089
00090 void
00091 internal_reference_types ()
00092 {
00093 reference_types_internal = 1;
00094 }
00095
00096
00097
00098 tree
00099 get_pending_sizes ()
00100 {
00101 tree chain = pending_sizes;
00102 tree t;
00103
00104
00105 for (t = chain; t; t = TREE_CHAIN (t))
00106 SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = current_function_decl;
00107
00108 pending_sizes = 0;
00109 return chain;
00110 }
00111
00112
00113
00114 int
00115 is_pending_size (expr)
00116 tree expr;
00117 {
00118 tree t;
00119
00120 for (t = pending_sizes; t; t = TREE_CHAIN (t))
00121 if (TREE_VALUE (t) == expr)
00122 return 1;
00123 return 0;
00124 }
00125
00126
00127
00128 void
00129 put_pending_size (expr)
00130 tree expr;
00131 {
00132
00133
00134 while (TREE_CODE_CLASS (TREE_CODE (expr)) == '1'
00135 || (TREE_CODE_CLASS (TREE_CODE (expr)) == '2'
00136 && TREE_CONSTANT (TREE_OPERAND (expr, 1))))
00137 expr = TREE_OPERAND (expr, 0);
00138
00139 if (TREE_CODE (expr) == SAVE_EXPR)
00140 pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes);
00141 }
00142
00143
00144
00145
00146 void
00147 put_pending_sizes (chain)
00148 tree chain;
00149 {
00150 if (pending_sizes)
00151 abort ();
00152
00153 pending_sizes = chain;
00154 }
00155
00156
00157
00158
00159 tree
00160 variable_size (size)
00161 tree size;
00162 {
00163
00164
00165
00166
00167 if (TREE_CONSTANT (size)
00168 || (*lang_hooks.decls.global_bindings_p) () < 0
00169 || contains_placeholder_p (size))
00170 return size;
00171
00172 size = save_expr (size);
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 if (TREE_CODE (size) == SAVE_EXPR)
00183 SAVE_EXPR_PERSISTENT_P (size) = 1;
00184
00185 if ((*lang_hooks.decls.global_bindings_p) ())
00186 {
00187 if (TREE_CONSTANT (size))
00188 error ("type size can't be explicitly evaluated");
00189 else
00190 error ("variable-size type declared outside of any function");
00191
00192 return size_one_node;
00193 }
00194
00195 if (immediate_size_expand)
00196
00197
00198 expand_expr (size, expand_expr (integer_zero_node, NULL_RTX, VOIDmode, 0),
00199 VOIDmode, 0);
00200 else if (cfun != 0 && cfun->x_dont_save_pending_sizes_p)
00201
00202
00203 ;
00204 else
00205 put_pending_size (size);
00206
00207 return size;
00208 }
00209
00210 #ifndef MAX_FIXED_MODE_SIZE
00211 #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
00212 #endif
00213
00214
00215
00216
00217
00218
00219 enum machine_mode
00220 mode_for_size (size, class, limit)
00221 unsigned int size;
00222 enum mode_class class;
00223 int limit;
00224 {
00225 enum machine_mode mode;
00226
00227 if (limit && size > MAX_FIXED_MODE_SIZE)
00228 return BLKmode;
00229
00230
00231 for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
00232 mode = GET_MODE_WIDER_MODE (mode))
00233 if (GET_MODE_BITSIZE (mode) == size)
00234 return mode;
00235
00236 return BLKmode;
00237 }
00238
00239
00240
00241 enum machine_mode
00242 mode_for_size_tree (size, class, limit)
00243 tree size;
00244 enum mode_class class;
00245 int limit;
00246 {
00247 if (TREE_CODE (size) != INTEGER_CST
00248
00249
00250
00251 || compare_tree_int (size, 1000) > 0)
00252 return BLKmode;
00253 else
00254 return mode_for_size (TREE_INT_CST_LOW (size), class, limit);
00255 }
00256
00257
00258
00259
00260 enum machine_mode
00261 smallest_mode_for_size (size, class)
00262 unsigned int size;
00263 enum mode_class class;
00264 {
00265 enum machine_mode mode;
00266
00267
00268
00269 for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
00270 mode = GET_MODE_WIDER_MODE (mode))
00271 if (GET_MODE_BITSIZE (mode) >= size)
00272 return mode;
00273
00274 abort ();
00275 }
00276
00277
00278
00279 enum machine_mode
00280 int_mode_for_mode (mode)
00281 enum machine_mode mode;
00282 {
00283 switch (GET_MODE_CLASS (mode))
00284 {
00285 case MODE_INT:
00286 case MODE_PARTIAL_INT:
00287 break;
00288
00289 case MODE_COMPLEX_INT:
00290 case MODE_COMPLEX_FLOAT:
00291 case MODE_FLOAT:
00292 case MODE_VECTOR_INT:
00293 case MODE_VECTOR_FLOAT:
00294 mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
00295 break;
00296
00297 case MODE_RANDOM:
00298 if (mode == BLKmode)
00299 break;
00300
00301
00302
00303 case MODE_CC:
00304 default:
00305 abort ();
00306 }
00307
00308 return mode;
00309 }
00310
00311
00312
00313
00314 unsigned int
00315 get_mode_alignment (mode)
00316 enum machine_mode mode;
00317 {
00318 unsigned int alignment;
00319
00320 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
00321 || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
00322 alignment = GET_MODE_UNIT_SIZE (mode);
00323 else
00324 alignment = GET_MODE_SIZE (mode);
00325
00326
00327 alignment = alignment & -alignment;
00328 alignment *= BITS_PER_UNIT;
00329
00330 alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment));
00331 return alignment;
00332 }
00333
00334
00335
00336
00337 tree
00338 round_up (value, divisor)
00339 tree value;
00340 int divisor;
00341 {
00342 tree arg = size_int_type (divisor, TREE_TYPE (value));
00343
00344 return size_binop (MULT_EXPR, size_binop (CEIL_DIV_EXPR, value, arg), arg);
00345 }
00346
00347
00348
00349 tree
00350 round_down (value, divisor)
00351 tree value;
00352 int divisor;
00353 {
00354 tree arg = size_int_type (divisor, TREE_TYPE (value));
00355
00356 return size_binop (MULT_EXPR, size_binop (FLOOR_DIV_EXPR, value, arg), arg);
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 void
00373 layout_decl (decl, known_align)
00374 tree decl;
00375 unsigned int known_align;
00376 {
00377 tree type = TREE_TYPE (decl);
00378 enum tree_code code = TREE_CODE (decl);
00379 rtx rtl = NULL_RTX;
00380
00381 if (code == CONST_DECL)
00382 return;
00383 else if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
00384 && code != TYPE_DECL && code != FIELD_DECL)
00385 abort ();
00386
00387 rtl = DECL_RTL_IF_SET (decl);
00388
00389 if (type == error_mark_node)
00390 type = void_type_node;
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
00403 if (DECL_MODE (decl) == VOIDmode)
00404 DECL_MODE (decl) = TYPE_MODE (type);
00405
00406 if (DECL_SIZE (decl) == 0)
00407 {
00408 DECL_SIZE (decl) = TYPE_SIZE (type);
00409 DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
00410 }
00411 else
00412 DECL_SIZE_UNIT (decl)
00413 = convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
00414 bitsize_unit_node));
00415
00416
00417
00418
00419 if (! (code == FIELD_DECL && DECL_BIT_FIELD (decl))
00420 && (DECL_ALIGN (decl) == 0
00421 || (! (code == FIELD_DECL && DECL_PACKED (decl))
00422 && TYPE_ALIGN (type) > DECL_ALIGN (decl))))
00423 {
00424 DECL_ALIGN (decl) = TYPE_ALIGN (type);
00425 DECL_USER_ALIGN (decl) = 0;
00426 }
00427
00428
00429 if (code == FIELD_DECL)
00430 {
00431 DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0;
00432 if (maximum_field_alignment != 0)
00433 DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
00434
00435
00436
00437
00438
00439 else if (DECL_PACKED (decl)
00440 && (DECL_NONADDRESSABLE_P (decl)
00441 || DECL_SIZE_UNIT (decl) == 0
00442 || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
00443 {
00444 DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
00445 DECL_USER_ALIGN (decl) = 0;
00446 }
00447 }
00448
00449
00450
00451
00452 if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
00453 && TYPE_SIZE (type) != 0
00454 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
00455 && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
00456 {
00457 enum machine_mode xmode
00458 = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
00459
00460 if (xmode != BLKmode && known_align >= GET_MODE_ALIGNMENT (xmode))
00461 {
00462 DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
00463 DECL_ALIGN (decl));
00464 DECL_MODE (decl) = xmode;
00465 DECL_BIT_FIELD (decl) = 0;
00466 }
00467 }
00468
00469
00470 if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
00471 && TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
00472 && known_align >= TYPE_ALIGN (type)
00473 && DECL_ALIGN (decl) >= TYPE_ALIGN (type)
00474 && DECL_SIZE_UNIT (decl) != 0)
00475 DECL_BIT_FIELD (decl) = 0;
00476
00477
00478 if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
00479 DECL_SIZE (decl) = variable_size (DECL_SIZE (decl));
00480 if (DECL_SIZE_UNIT (decl) != 0
00481 && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST)
00482 DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl));
00483
00484
00485 if (warn_larger_than
00486 && (code == VAR_DECL || code == PARM_DECL)
00487 && ! DECL_EXTERNAL (decl))
00488 {
00489 tree size = DECL_SIZE_UNIT (decl);
00490
00491 if (size != 0 && TREE_CODE (size) == INTEGER_CST
00492 && compare_tree_int (size, larger_than_size) > 0)
00493 {
00494 unsigned int size_as_int = TREE_INT_CST_LOW (size);
00495
00496 if (compare_tree_int (size, size_as_int) == 0)
00497 warning_with_decl (decl, "size of `%s' is %d bytes", size_as_int);
00498 else
00499 warning_with_decl (decl, "size of `%s' is larger than %d bytes",
00500 larger_than_size);
00501 }
00502 }
00503
00504
00505 if (rtl)
00506 {
00507 PUT_MODE (rtl, DECL_MODE (decl));
00508 SET_DECL_RTL (decl, 0);
00509 set_mem_attributes (rtl, decl, 1);
00510 SET_DECL_RTL (decl, rtl);
00511 }
00512 }
00513
00514
00515
00516
00517 void (*lang_adjust_rli) PARAMS ((record_layout_info)) = 0;
00518
00519 void
00520 set_lang_adjust_rli (f)
00521 void (*f) PARAMS ((record_layout_info));
00522 {
00523 lang_adjust_rli = f;
00524 }
00525
00526 #ifdef SGI_MONGOOSE
00527
00528
00529 static void
00530 assign_field_ids (tree rec)
00531 {
00532 register tree field;
00533 int next_field_id;
00534 int fields_in_field;
00535
00536 if (TYPE_FIELD_IDS_USED(rec) > 0)
00537 return;
00538 next_field_id = 1;
00539 for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field))
00540 {
00541 DECL_FIELD_ID(field) = next_field_id;
00542 fields_in_field = TYPE_FIELD_IDS_USED(TREE_TYPE(field));
00543 if (fields_in_field == 0 &&
00544 (TREE_CODE(TREE_TYPE(field)) == RECORD_TYPE ||
00545 TREE_CODE(TREE_TYPE(field)) == UNION_TYPE ||
00546 TREE_CODE(TREE_TYPE(field)) == QUAL_UNION_TYPE)) {
00547 assign_field_ids(TREE_TYPE(field));
00548 fields_in_field = TYPE_FIELD_IDS_USED(TREE_TYPE(field));
00549 }
00550 next_field_id += fields_in_field + 1;
00551 }
00552
00553 TYPE_FIELD_IDS_USED(rec) = next_field_id - 1;
00554 }
00555 #endif
00556
00557
00558
00559
00560
00561
00562
00563
00564 record_layout_info
00565 start_record_layout (t)
00566 tree t;
00567 {
00568 record_layout_info rli
00569 = (record_layout_info) xmalloc (sizeof (struct record_layout_info_s));
00570
00571 rli->t = t;
00572
00573
00574
00575
00576 rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));
00577 rli->unpacked_align = rli->unpadded_align = rli->record_align;
00578 rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);
00579
00580 #ifdef STRUCTURE_SIZE_BOUNDARY
00581
00582 if (! TYPE_PACKED (t))
00583 rli->record_align = MAX (rli->record_align, STRUCTURE_SIZE_BOUNDARY);
00584 #endif
00585
00586 rli->offset = size_zero_node;
00587 rli->bitpos = bitsize_zero_node;
00588 rli->prev_field = 0;
00589 rli->pending_statics = 0;
00590 rli->packed_maybe_necessary = 0;
00591
00592 return rli;
00593 }
00594
00595
00596
00597
00598 tree
00599 bit_from_pos (offset, bitpos)
00600 tree offset, bitpos;
00601 {
00602 return size_binop (PLUS_EXPR, bitpos,
00603 size_binop (MULT_EXPR, convert (bitsizetype, offset),
00604 bitsize_unit_node));
00605 }
00606
00607 tree
00608 byte_from_pos (offset, bitpos)
00609 tree offset, bitpos;
00610 {
00611 return size_binop (PLUS_EXPR, offset,
00612 convert (sizetype,
00613 size_binop (TRUNC_DIV_EXPR, bitpos,
00614 bitsize_unit_node)));
00615 }
00616
00617 void
00618 pos_from_byte (poffset, pbitpos, off_align, pos)
00619 tree *poffset, *pbitpos;
00620 unsigned int off_align;
00621 tree pos;
00622 {
00623 *poffset
00624 = size_binop (MULT_EXPR,
00625 convert (sizetype,
00626 size_binop (FLOOR_DIV_EXPR, pos,
00627 bitsize_int (off_align
00628 / BITS_PER_UNIT))),
00629 size_int (off_align / BITS_PER_UNIT));
00630 *pbitpos = size_binop (MULT_EXPR,
00631 size_binop (FLOOR_MOD_EXPR, pos,
00632 bitsize_int (off_align / BITS_PER_UNIT)),
00633 bitsize_unit_node);
00634 }
00635
00636 void
00637 pos_from_bit (poffset, pbitpos, off_align, pos)
00638 tree *poffset, *pbitpos;
00639 unsigned int off_align;
00640 tree pos;
00641 {
00642 *poffset = size_binop (MULT_EXPR,
00643 convert (sizetype,
00644 size_binop (FLOOR_DIV_EXPR, pos,
00645 bitsize_int (off_align))),
00646 size_int (off_align / BITS_PER_UNIT));
00647 *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, bitsize_int (off_align));
00648 }
00649
00650
00651
00652
00653 void
00654 normalize_offset (poffset, pbitpos, off_align)
00655 tree *poffset, *pbitpos;
00656 unsigned int off_align;
00657 {
00658
00659
00660 if (compare_tree_int (*pbitpos, off_align) >= 0)
00661 {
00662 tree extra_aligns = size_binop (FLOOR_DIV_EXPR, *pbitpos,
00663 bitsize_int (off_align));
00664
00665 *poffset
00666 = size_binop (PLUS_EXPR, *poffset,
00667 size_binop (MULT_EXPR, convert (sizetype, extra_aligns),
00668 size_int (off_align / BITS_PER_UNIT)));
00669
00670 *pbitpos
00671 = size_binop (FLOOR_MOD_EXPR, *pbitpos, bitsize_int (off_align));
00672 }
00673 }
00674
00675
00676
00677 void
00678 debug_rli (rli)
00679 record_layout_info rli;
00680 {
00681 print_node_brief (stderr, "type", rli->t, 0);
00682 print_node_brief (stderr, "\noffset", rli->offset, 0);
00683 print_node_brief (stderr, " bitpos", rli->bitpos, 0);
00684
00685 fprintf (stderr, "\naligns: rec = %u, unpack = %u, unpad = %u, off = %u\n",
00686 rli->record_align, rli->unpacked_align, rli->unpadded_align,
00687 rli->offset_align);
00688 if (rli->packed_maybe_necessary)
00689 fprintf (stderr, "packed may be necessary\n");
00690
00691 if (rli->pending_statics)
00692 {
00693 fprintf (stderr, "pending statics:\n");
00694 debug_tree (rli->pending_statics);
00695 }
00696 }
00697
00698
00699
00700
00701 void
00702 normalize_rli (rli)
00703 record_layout_info rli;
00704 {
00705 normalize_offset (&rli->offset, &rli->bitpos, rli->offset_align);
00706 }
00707
00708
00709
00710 tree
00711 rli_size_unit_so_far (rli)
00712 record_layout_info rli;
00713 {
00714 return byte_from_pos (rli->offset, rli->bitpos);
00715 }
00716
00717
00718
00719 tree
00720 rli_size_so_far (rli)
00721 record_layout_info rli;
00722 {
00723 return bit_from_pos (rli->offset, rli->bitpos);
00724 }
00725
00726
00727
00728
00729
00730
00731 static unsigned int
00732 update_alignment_for_field (rli, field, known_align)
00733 record_layout_info rli;
00734 tree field;
00735 unsigned int known_align;
00736 {
00737
00738 unsigned int desired_align;
00739
00740 tree type = TREE_TYPE (field);
00741
00742 bool user_align;
00743
00744
00745
00746
00747 desired_align = DECL_ALIGN (field);
00748 user_align = DECL_USER_ALIGN (field);
00749 layout_decl (field, known_align);
00750 if (! DECL_PACKED (field))
00751 {
00752 desired_align = DECL_ALIGN (field);
00753 user_align = DECL_USER_ALIGN (field);
00754 }
00755
00756
00757
00758
00759 #ifdef BIGGEST_FIELD_ALIGNMENT
00760 if (!user_align)
00761 desired_align
00762 = MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
00763 #endif
00764
00765 #ifdef ADJUST_FIELD_ALIGN
00766 if (!user_align)
00767 desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
00768 #endif
00769
00770
00771
00772
00773 if ((* targetm.ms_bitfield_layout_p) (rli->t)
00774 && type != error_mark_node
00775 && DECL_BIT_FIELD_TYPE (field)
00776 && ! integer_zerop (TYPE_SIZE (type)))
00777 {
00778
00779
00780
00781
00782
00783
00784 if (! integer_zerop (DECL_SIZE (field))
00785 ? ! DECL_PACKED (field)
00786 : (rli->prev_field
00787 && DECL_BIT_FIELD_TYPE (rli->prev_field)
00788 && ! integer_zerop (DECL_SIZE (rli->prev_field))))
00789 {
00790 unsigned int type_align = TYPE_ALIGN (type);
00791 type_align = MAX (type_align, desired_align);
00792 if (maximum_field_alignment != 0)
00793 type_align = MIN (type_align, maximum_field_alignment);
00794 rli->record_align = MAX (rli->record_align, type_align);
00795 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
00796 rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
00797 }
00798 else
00799 desired_align = 1;
00800 }
00801 else
00802 #ifdef PCC_BITFIELD_TYPE_MATTERS
00803 if (PCC_BITFIELD_TYPE_MATTERS && type != error_mark_node
00804 && ! (* targetm.ms_bitfield_layout_p) (rli->t)
00805 && DECL_BIT_FIELD_TYPE (field)
00806 && ! integer_zerop (TYPE_SIZE (type)))
00807 {
00808
00809
00810
00811
00812 if (! integer_zerop (DECL_SIZE (field)))
00813 rli->record_align = MAX (rli->record_align, desired_align);
00814 else if (! DECL_PACKED (field) && !user_align)
00815 desired_align = TYPE_ALIGN (type);
00816
00817
00818
00819 if (DECL_NAME (field) != 0)
00820 {
00821 unsigned int type_align = TYPE_ALIGN (type);
00822
00823 #ifdef ADJUST_FIELD_ALIGN
00824 if (! TYPE_USER_ALIGN (type))
00825 type_align = ADJUST_FIELD_ALIGN (field, type_align);
00826 #endif
00827
00828 if (maximum_field_alignment != 0)
00829 type_align = MIN (type_align, maximum_field_alignment);
00830 else if (DECL_PACKED (field))
00831 type_align = MIN (type_align, BITS_PER_UNIT);
00832
00833 rli->record_align = MAX (rli->record_align, type_align);
00834 rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
00835 if (warn_packed)
00836 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
00837 user_align |= TYPE_USER_ALIGN (type);
00838 }
00839 }
00840 else
00841 #endif
00842 {
00843 rli->record_align = MAX (rli->record_align, desired_align);
00844 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
00845 rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
00846 }
00847
00848 TYPE_USER_ALIGN (rli->t) |= user_align;
00849
00850 DECL_ALIGN (field) = desired_align;
00851
00852 return desired_align;
00853 }
00854
00855
00856
00857 static void
00858 place_union_field (rli, field)
00859 record_layout_info rli;
00860 tree field;
00861 {
00862 update_alignment_for_field (rli, field, 0);
00863
00864 DECL_FIELD_OFFSET (field) = size_zero_node;
00865 DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
00866 SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
00867
00868
00869
00870 if (TREE_CODE (rli->t) == UNION_TYPE)
00871 rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
00872 else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
00873 rli->offset = fold (build (COND_EXPR, sizetype,
00874 DECL_QUALIFIER (field),
00875 DECL_SIZE_UNIT (field), rli->offset));
00876 }
00877
00878
00879
00880
00881
00882
00883 void
00884 place_field (rli, field)
00885 record_layout_info rli;
00886 tree field;
00887 {
00888
00889 unsigned int desired_align;
00890
00891
00892 unsigned int known_align;
00893 unsigned int actual_align;
00894
00895 tree type = TREE_TYPE (field);
00896
00897 if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
00898 return;
00899
00900
00901
00902
00903
00904 if (TREE_CODE (field) == VAR_DECL)
00905 {
00906 rli->pending_statics = tree_cons (NULL_TREE, field,
00907 rli->pending_statics);
00908 return;
00909 }
00910
00911
00912
00913 else if (TREE_CODE (field) != FIELD_DECL)
00914 return;
00915
00916
00917
00918 else if (TREE_CODE (rli->t) != RECORD_TYPE)
00919 {
00920 place_union_field (rli, field);
00921 return;
00922 }
00923
00924
00925
00926 if (! integer_zerop (rli->bitpos))
00927 known_align = (tree_low_cst (rli->bitpos, 1)
00928 & - tree_low_cst (rli->bitpos, 1));
00929 else if (integer_zerop (rli->offset))
00930 known_align = BIGGEST_ALIGNMENT;
00931 else if (host_integerp (rli->offset, 1))
00932 known_align = (BITS_PER_UNIT
00933 * (tree_low_cst (rli->offset, 1)
00934 & - tree_low_cst (rli->offset, 1)));
00935 else
00936 known_align = rli->offset_align;
00937
00938 desired_align = update_alignment_for_field (rli, field, known_align);
00939
00940 if (warn_packed && DECL_PACKED (field))
00941 {
00942 if (known_align > TYPE_ALIGN (type))
00943 {
00944 if (TYPE_ALIGN (type) > desired_align)
00945 {
00946 if (STRICT_ALIGNMENT)
00947 warning_with_decl (field, "packed attribute causes inefficient alignment for `%s'");
00948 else
00949 warning_with_decl (field, "packed attribute is unnecessary for `%s'");
00950 }
00951 }
00952 else
00953 rli->packed_maybe_necessary = 1;
00954 }
00955
00956
00957
00958 if (known_align < desired_align)
00959 {
00960
00961
00962
00963 if (warn_padded)
00964 warning_with_decl (field, "padding struct to align `%s'");
00965
00966
00967
00968 if (desired_align < rli->offset_align)
00969 rli->bitpos = round_up (rli->bitpos, desired_align);
00970 else
00971 {
00972
00973 rli->offset
00974 = size_binop (PLUS_EXPR, rli->offset,
00975 convert (sizetype,
00976 size_binop (CEIL_DIV_EXPR, rli->bitpos,
00977 bitsize_unit_node)));
00978 rli->bitpos = bitsize_zero_node;
00979
00980 rli->offset = round_up (rli->offset, desired_align / BITS_PER_UNIT);
00981 }
00982
00983 if (! TREE_CONSTANT (rli->offset))
00984 rli->offset_align = desired_align;
00985
00986 }
00987
00988
00989
00990 #ifdef PCC_BITFIELD_TYPE_MATTERS
00991 if (PCC_BITFIELD_TYPE_MATTERS
00992 && ! (* targetm.ms_bitfield_layout_p) (rli->t)
00993 && TREE_CODE (field) == FIELD_DECL
00994 && type != error_mark_node
00995 && DECL_BIT_FIELD (field)
00996 && ! DECL_PACKED (field)
00997 && maximum_field_alignment == 0
00998 && ! integer_zerop (DECL_SIZE (field))
00999 && host_integerp (DECL_SIZE (field), 1)
01000 && host_integerp (rli->offset, 1)
01001 && host_integerp (TYPE_SIZE (type), 1))
01002 {
01003 unsigned int type_align = TYPE_ALIGN (type);
01004 tree dsize = DECL_SIZE (field);
01005 HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
01006 HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
01007 HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
01008
01009 #ifdef ADJUST_FIELD_ALIGN
01010 if (! TYPE_USER_ALIGN (type))
01011 type_align = ADJUST_FIELD_ALIGN (field, type_align);
01012 #endif
01013
01014
01015
01016 if ((((offset * BITS_PER_UNIT + bit_offset + field_size +
01017 type_align - 1)
01018 / type_align)
01019 - (offset * BITS_PER_UNIT + bit_offset) / type_align)
01020 > tree_low_cst (TYPE_SIZE (type), 1) / type_align)
01021 rli->bitpos = round_up (rli->bitpos, type_align);
01022
01023 TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
01024 }
01025 #endif
01026
01027 #ifdef BITFIELD_NBYTES_LIMITED
01028 if (BITFIELD_NBYTES_LIMITED
01029 && ! (* targetm.ms_bitfield_layout_p) (rli->t)
01030 && TREE_CODE (field) == FIELD_DECL
01031 && type != error_mark_node
01032 && DECL_BIT_FIELD_TYPE (field)
01033 && ! DECL_PACKED (field)
01034 && ! integer_zerop (DECL_SIZE (field))
01035 && host_integerp (DECL_SIZE (field), 1)
01036 && host_integerp (rli->offset, 1)
01037 && host_integerp (TYPE_SIZE (type), 1))
01038 {
01039 unsigned int type_align = TYPE_ALIGN (type);
01040 tree dsize = DECL_SIZE (field);
01041 HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
01042 HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
01043 HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
01044
01045 #ifdef ADJUST_FIELD_ALIGN
01046 if (! TYPE_USER_ALIGN (type))
01047 type_align = ADJUST_FIELD_ALIGN (field, type_align);
01048 #endif
01049
01050 if (maximum_field_alignment != 0)
01051 type_align = MIN (type_align, maximum_field_alignment);
01052
01053
01054 else if (DECL_PACKED (field))
01055 type_align = MIN (type_align, BITS_PER_UNIT);
01056
01057
01058
01059
01060
01061 if ((offset * BITS_PER_UNIT + bit_offset) / type_align
01062 != ((offset * BITS_PER_UNIT + bit_offset + field_size - 1)
01063 / type_align))
01064 rli->bitpos = round_up (rli->bitpos, type_align);
01065
01066 TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
01067 }
01068 #endif
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 if ((* targetm.ms_bitfield_layout_p) (rli->t)
01085 && ((DECL_BIT_FIELD_TYPE (field) && ! DECL_PACKED (field))
01086 || (rli->prev_field && ! DECL_PACKED (rli->prev_field))))
01087 {
01088
01089
01090 tree prev_saved = rli->prev_field;
01091
01092
01093
01094 if (rli->prev_field )
01095 {
01096
01097
01098
01099
01100
01101
01102 if (DECL_BIT_FIELD_TYPE (field)
01103 && !integer_zerop (DECL_SIZE (field))
01104 && !integer_zerop (DECL_SIZE (rli->prev_field))
01105 && simple_cst_equal (TYPE_SIZE (type),
01106 TYPE_SIZE (TREE_TYPE (rli->prev_field))) )
01107 {
01108
01109
01110
01111 int bitsize = TREE_INT_CST_LOW (DECL_SIZE (field));
01112 tree type_size = TYPE_SIZE(TREE_TYPE(rli->prev_field));
01113
01114 if (rli->remaining_in_alignment < bitsize)
01115 {
01116
01117 rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
01118 rli->bitpos = size_binop (PLUS_EXPR,
01119 type_size,
01120 DECL_FIELD_BIT_OFFSET(rli->prev_field));
01121 rli->prev_field = field;
01122 rli->remaining_in_alignment = TREE_INT_CST_LOW (type_size);
01123 }
01124 rli->remaining_in_alignment -= bitsize;
01125 }
01126 else
01127 {
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137 if (!integer_zerop (DECL_SIZE (rli->prev_field)))
01138 {
01139 tree type_size = TYPE_SIZE(TREE_TYPE(rli->prev_field));
01140 rli->bitpos = size_binop (PLUS_EXPR,
01141 type_size,
01142 DECL_FIELD_BIT_OFFSET(rli->prev_field));
01143 }
01144 else
01145 {
01146
01147
01148 prev_saved = NULL;
01149 }
01150
01151
01152
01153 if (!DECL_BIT_FIELD_TYPE(field)
01154 || integer_zerop (DECL_SIZE (field)))
01155 {
01156 rli->prev_field = NULL;
01157 }
01158 }
01159 normalize_rli (rli);
01160 }
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 if (!DECL_BIT_FIELD_TYPE (field)
01175 || ( prev_saved != NULL
01176 ? !simple_cst_equal (TYPE_SIZE (type),
01177 TYPE_SIZE (TREE_TYPE (prev_saved)))
01178 : !integer_zerop (DECL_SIZE (field)) ))
01179 {
01180 unsigned int type_align = 8;
01181
01182
01183
01184
01185
01186
01187 if (DECL_SIZE (field) != NULL)
01188 rli->remaining_in_alignment
01189 = TREE_INT_CST_LOW (TYPE_SIZE(TREE_TYPE(field)))
01190 - TREE_INT_CST_LOW (DECL_SIZE (field));
01191
01192
01193 if (!DECL_PACKED(field))
01194 type_align = MAX(TYPE_ALIGN (type), type_align);
01195
01196 if (prev_saved
01197 && DECL_BIT_FIELD_TYPE (prev_saved)
01198
01199
01200
01201 && ! integer_zerop (DECL_SIZE (prev_saved)))
01202 type_align = MAX (type_align,
01203 TYPE_ALIGN (TREE_TYPE (prev_saved)));
01204
01205 if (maximum_field_alignment != 0)
01206 type_align = MIN (type_align, maximum_field_alignment);
01207
01208 rli->bitpos = round_up (rli->bitpos, type_align);
01209
01210
01211 rli->prev_field = NULL;
01212 }
01213 }
01214
01215
01216 normalize_rli (rli);
01217 DECL_FIELD_OFFSET (field) = rli->offset;
01218 DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
01219 SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
01220
01221
01222
01223
01224 if (! integer_zerop (DECL_FIELD_BIT_OFFSET (field)))
01225 actual_align = (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
01226 & - tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1));
01227 else if (integer_zerop (DECL_FIELD_OFFSET (field)))
01228 actual_align = BIGGEST_ALIGNMENT;
01229 else if (host_integerp (DECL_FIELD_OFFSET (field), 1))
01230 actual_align = (BITS_PER_UNIT
01231 * (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
01232 & - tree_low_cst (DECL_FIELD_OFFSET (field), 1)));
01233 else
01234 actual_align = DECL_OFFSET_ALIGN (field);
01235
01236 if (known_align != actual_align)
01237 layout_decl (field, actual_align);
01238
01239
01240 if (rli->prev_field == NULL && DECL_BIT_FIELD_TYPE(field))
01241 rli->prev_field = field;
01242
01243
01244
01245
01246
01247
01248
01249
01250 if (DECL_SIZE (field) == 0)
01251 ;
01252 else if (TREE_CODE (DECL_SIZE_UNIT (field)) != INTEGER_CST
01253 || TREE_CONSTANT_OVERFLOW (DECL_SIZE_UNIT (field)))
01254 {
01255 rli->offset
01256 = size_binop (PLUS_EXPR, rli->offset,
01257 convert (sizetype,
01258 size_binop (CEIL_DIV_EXPR, rli->bitpos,
01259 bitsize_unit_node)));
01260 rli->offset
01261 = size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
01262 rli->bitpos = bitsize_zero_node;
01263 rli->offset_align = MIN (rli->offset_align, DECL_ALIGN (field));
01264 }
01265 else
01266 {
01267 rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
01268 normalize_rli (rli);
01269 }
01270 }
01271
01272
01273
01274
01275
01276 static void
01277 finalize_record_size (rli)
01278 record_layout_info rli;
01279 {
01280 tree unpadded_size, unpadded_size_unit;
01281
01282
01283
01284 rli->offset_align = BITS_PER_UNIT;
01285 normalize_rli (rli);
01286
01287
01288 #ifdef ROUND_TYPE_ALIGN
01289 TYPE_ALIGN (rli->t) = ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t),
01290 rli->record_align);
01291 #else
01292 TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align);
01293 #endif
01294
01295
01296
01297
01298 unpadded_size = rli_size_so_far (rli);
01299 unpadded_size_unit = rli_size_unit_so_far (rli);
01300 if (! integer_zerop (rli->bitpos))
01301 unpadded_size_unit
01302 = size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);
01303
01304
01305
01306 if (TYPE_BINFO (rli->t) && TREE_VEC_LENGTH (TYPE_BINFO (rli->t)) > 6)
01307 {
01308 TYPE_BINFO_SIZE (rli->t) = unpadded_size;
01309 TYPE_BINFO_SIZE_UNIT (rli->t) = unpadded_size_unit;
01310 }
01311
01312
01313 #ifdef ROUND_TYPE_SIZE
01314 TYPE_SIZE (rli->t) = ROUND_TYPE_SIZE (rli->t, unpadded_size,
01315 TYPE_ALIGN (rli->t));
01316 TYPE_SIZE_UNIT (rli->t)
01317 = ROUND_TYPE_SIZE_UNIT (rli->t, unpadded_size_unit,
01318 TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
01319 #else
01320 TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
01321 TYPE_SIZE_UNIT (rli->t) = round_up (unpadded_size_unit,
01322 TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
01323 #endif
01324
01325 if (warn_padded && TREE_CONSTANT (unpadded_size)
01326 && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
01327 warning ("padding struct size to alignment boundary");
01328
01329 if (warn_packed && TREE_CODE (rli->t) == RECORD_TYPE
01330 && TYPE_PACKED (rli->t) && ! rli->packed_maybe_necessary
01331 && TREE_CONSTANT (unpadded_size))
01332 {
01333 tree unpacked_size;
01334
01335 #ifdef ROUND_TYPE_ALIGN
01336 rli->unpacked_align
01337 = ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t), rli->unpacked_align);
01338 #else
01339 rli->unpacked_align = MAX (TYPE_ALIGN (rli->t), rli->unpacked_align);
01340 #endif
01341
01342 #ifdef ROUND_TYPE_SIZE
01343 unpacked_size = ROUND_TYPE_SIZE (rli->t, TYPE_SIZE (rli->t),
01344 rli->unpacked_align);
01345 #else
01346 unpacked_size = round_up (TYPE_SIZE (rli->t), rli->unpacked_align);
01347 #endif
01348
01349 if (simple_cst_equal (unpacked_size, TYPE_SIZE (rli->t)))
01350 {
01351 TYPE_PACKED (rli->t) = 0;
01352
01353 if (TYPE_NAME (rli->t))
01354 {
01355 const char *name;
01356
01357 if (TREE_CODE (TYPE_NAME (rli->t)) == IDENTIFIER_NODE)
01358 name = IDENTIFIER_POINTER (TYPE_NAME (rli->t));
01359 else
01360 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (rli->t)));
01361
01362 if (STRICT_ALIGNMENT)
01363 warning ("packed attribute causes inefficient alignment for `%s'", name);
01364 else
01365 warning ("packed attribute is unnecessary for `%s'", name);
01366 }
01367 else
01368 {
01369 if (STRICT_ALIGNMENT)
01370 warning ("packed attribute causes inefficient alignment");
01371 else
01372 warning ("packed attribute is unnecessary");
01373 }
01374 }
01375 }
01376 }
01377
01378
01379
01380 void
01381 compute_record_mode (type)
01382 tree type;
01383 {
01384 tree field;
01385 enum machine_mode mode = VOIDmode;
01386
01387
01388
01389
01390
01391 TYPE_MODE (type) = BLKmode;
01392
01393 if (! host_integerp (TYPE_SIZE (type), 1))
01394 return;
01395
01396
01397
01398
01399 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
01400 {
01401 unsigned HOST_WIDE_INT bitpos;
01402
01403 if (TREE_CODE (field) != FIELD_DECL)
01404 continue;
01405
01406 if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK
01407 || (TYPE_MODE (TREE_TYPE (field)) == BLKmode
01408 && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field)))
01409 || ! host_integerp (bit_position (field), 1)
01410 || DECL_SIZE (field) == 0
01411 || ! host_integerp (DECL_SIZE (field), 1))
01412 return;
01413
01414 bitpos = int_bit_position (field);
01415
01416
01417
01418 if (bitpos / BITS_PER_WORD
01419 != ((tree_low_cst (DECL_SIZE (field), 1) + bitpos - 1)
01420 / BITS_PER_WORD)
01421
01422 && tree_low_cst (DECL_SIZE (field), 1) % BITS_PER_WORD != 0)
01423 return;
01424
01425
01426
01427
01428 if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
01429 mode = DECL_MODE (field);
01430
01431 #ifdef MEMBER_TYPE_FORCES_BLK
01432
01433
01434
01435 if (MEMBER_TYPE_FORCES_BLK (field, mode))
01436 return;
01437 #endif
01438 }
01439
01440
01441
01442 if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode)
01443 TYPE_MODE (type) = mode;
01444 else
01445 TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
01446
01447
01448
01449 if (TYPE_MODE (type) != BLKmode
01450 && STRICT_ALIGNMENT
01451 && ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
01452 || TYPE_ALIGN (type) >= GET_MODE_ALIGNMENT (TYPE_MODE (type))))
01453 {
01454
01455
01456 TYPE_NO_FORCE_BLK (type) = 1;
01457 TYPE_MODE (type) = BLKmode;
01458 }
01459 }
01460
01461
01462
01463
01464 static void
01465 finalize_type_size (type)
01466 tree type;
01467 {
01468
01469
01470
01471
01472
01473 if (TYPE_MODE (type) != BLKmode && TYPE_MODE (type) != VOIDmode
01474 && (STRICT_ALIGNMENT
01475 || (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
01476 && TREE_CODE (type) != QUAL_UNION_TYPE
01477 && TREE_CODE (type) != ARRAY_TYPE)))
01478 {
01479 TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
01480 TYPE_USER_ALIGN (type) = 0;
01481 }
01482
01483
01484 #ifdef ROUND_TYPE_ALIGN
01485 TYPE_ALIGN (type)
01486 = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT);
01487 #endif
01488
01489
01490
01491 if (TYPE_SIZE_UNIT (type) == 0 && TYPE_SIZE (type) != 0)
01492
01493
01494
01495 TYPE_SIZE_UNIT (type)
01496 = convert (sizetype,
01497 size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type),
01498 bitsize_unit_node));
01499
01500 if (TYPE_SIZE (type) != 0)
01501 {
01502 #ifdef ROUND_TYPE_SIZE
01503 TYPE_SIZE (type)
01504 = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
01505 TYPE_SIZE_UNIT (type)
01506 = ROUND_TYPE_SIZE_UNIT (type, TYPE_SIZE_UNIT (type),
01507 TYPE_ALIGN (type) / BITS_PER_UNIT);
01508 #else
01509 TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type));
01510 TYPE_SIZE_UNIT (type)
01511 = round_up (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type) / BITS_PER_UNIT);
01512 #endif
01513 }
01514
01515
01516 if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
01517 TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
01518 if (TYPE_SIZE_UNIT (type) != 0
01519 && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
01520 TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type));
01521
01522
01523 if (TYPE_NEXT_VARIANT (type)
01524 || type != TYPE_MAIN_VARIANT (type))
01525 {
01526 tree variant;
01527
01528 tree size = TYPE_SIZE (type);
01529 tree size_unit = TYPE_SIZE_UNIT (type);
01530 unsigned int align = TYPE_ALIGN (type);
01531 unsigned int user_align = TYPE_USER_ALIGN (type);
01532 enum machine_mode mode = TYPE_MODE (type);
01533
01534
01535 for (variant = TYPE_MAIN_VARIANT (type);
01536 variant != 0;
01537 variant = TYPE_NEXT_VARIANT (variant))
01538 {
01539 TYPE_SIZE (variant) = size;
01540 TYPE_SIZE_UNIT (variant) = size_unit;
01541 TYPE_ALIGN (variant) = align;
01542 TYPE_USER_ALIGN (variant) = user_align;
01543 TYPE_MODE (variant) = mode;
01544 }
01545 }
01546 }
01547
01548
01549
01550
01551
01552
01553
01554 void
01555 finish_record_layout (rli, free_p)
01556 record_layout_info rli;
01557 int free_p;
01558 {
01559
01560 finalize_record_size (rli);
01561
01562
01563 compute_record_mode (rli->t);
01564
01565
01566 finalize_type_size (rli->t);
01567
01568
01569
01570 while (rli->pending_statics)
01571 {
01572 layout_decl (TREE_VALUE (rli->pending_statics), 0);
01573 rli->pending_statics = TREE_CHAIN (rli->pending_statics);
01574 }
01575
01576
01577 if (free_p)
01578 free (rli);
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591 void
01592 layout_type (type)
01593 tree type;
01594 {
01595 if (type == 0)
01596 abort ();
01597
01598
01599 if (TYPE_SIZE (type))
01600 return;
01601
01602 switch (TREE_CODE (type))
01603 {
01604 case LANG_TYPE:
01605
01606
01607 abort ();
01608
01609 case BOOLEAN_TYPE:
01610 if (TYPE_PRECISION (type) == 0)
01611 TYPE_PRECISION (type) = 1;
01612
01613
01614
01615 case INTEGER_TYPE:
01616 case ENUMERAL_TYPE:
01617 case CHAR_TYPE:
01618 if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
01619 && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
01620 TREE_UNSIGNED (type) = 1;
01621
01622 TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
01623 MODE_INT);
01624 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
01625 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
01626 break;
01627
01628 case REAL_TYPE:
01629 TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
01630 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
01631 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
01632 break;
01633
01634 case COMPLEX_TYPE:
01635 TREE_UNSIGNED (type) = TREE_UNSIGNED (TREE_TYPE (type));
01636 TYPE_MODE (type)
01637 = mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
01638 (TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
01639 ? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),
01640 0);
01641 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
01642 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
01643 break;
01644
01645 case VECTOR_TYPE:
01646 {
01647 tree subtype;
01648
01649 subtype = TREE_TYPE (type);
01650 TREE_UNSIGNED (type) = TREE_UNSIGNED (subtype);
01651 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
01652 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
01653 }
01654 break;
01655
01656 case VOID_TYPE:
01657
01658 TYPE_ALIGN (type) = 1;
01659 TYPE_USER_ALIGN (type) = 0;
01660 TYPE_MODE (type) = VOIDmode;
01661 break;
01662
01663 case OFFSET_TYPE:
01664 TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
01665 TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
01666
01667
01668 TYPE_MODE (type) = mode_for_size (POINTER_SIZE, MODE_INT, 0);
01669 break;
01670
01671 case FUNCTION_TYPE:
01672 case METHOD_TYPE:
01673 TYPE_MODE (type) = mode_for_size (2 * POINTER_SIZE, MODE_INT, 0);
01674 TYPE_SIZE (type) = bitsize_int (2 * POINTER_SIZE);
01675 TYPE_SIZE_UNIT (type) = size_int ((2 * POINTER_SIZE) / BITS_PER_UNIT);
01676 break;
01677
01678 case POINTER_TYPE:
01679 case REFERENCE_TYPE:
01680 {
01681 int nbits = ((TREE_CODE (type) == REFERENCE_TYPE
01682 && reference_types_internal)
01683 ? GET_MODE_BITSIZE (Pmode) : POINTER_SIZE);
01684
01685 TYPE_MODE (type) = nbits == POINTER_SIZE ? ptr_mode : Pmode;
01686 TYPE_SIZE (type) = bitsize_int (nbits);
01687 TYPE_SIZE_UNIT (type) = size_int (nbits / BITS_PER_UNIT);
01688 TREE_UNSIGNED (type) = 1;
01689 TYPE_PRECISION (type) = nbits;
01690 }
01691 break;
01692
01693 case ARRAY_TYPE:
01694 {
01695 tree index = TYPE_DOMAIN (type);
01696 tree element = TREE_TYPE (type);
01697
01698 build_pointer_type (element);
01699
01700
01701 if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
01702 && TYPE_SIZE (element))
01703 {
01704 tree ub = TYPE_MAX_VALUE (index);
01705 tree lb = TYPE_MIN_VALUE (index);
01706 tree length;
01707 tree element_size;
01708
01709
01710
01711 length = size_binop (PLUS_EXPR, size_one_node,
01712 convert (sizetype,
01713 fold (build (MINUS_EXPR,
01714 TREE_TYPE (lb),
01715 ub, lb))));
01716
01717
01718 element_size = TYPE_SIZE (element);
01719 if (TYPE_PACKED (type) && INTEGRAL_TYPE_P (element)
01720 && (integer_zerop (TYPE_MAX_VALUE (element))
01721 || integer_onep (TYPE_MAX_VALUE (element)))
01722 && host_integerp (TYPE_MIN_VALUE (element), 1))
01723 {
01724 HOST_WIDE_INT maxvalue
01725 = tree_low_cst (TYPE_MAX_VALUE (element), 1);
01726 HOST_WIDE_INT minvalue
01727 = tree_low_cst (TYPE_MIN_VALUE (element), 1);
01728
01729 if (maxvalue - minvalue == 1
01730 && (maxvalue == 1 || maxvalue == 0))
01731 element_size = integer_one_node;
01732 }
01733
01734 TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
01735 convert (bitsizetype, length));
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 if (TYPE_SIZE_UNIT (element) != 0 && ! integer_onep (element_size))
01746 TYPE_SIZE_UNIT (type)
01747 = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length);
01748 }
01749
01750
01751
01752
01753 #ifdef ROUND_TYPE_ALIGN
01754 TYPE_ALIGN (type)
01755 = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (element), BITS_PER_UNIT);
01756 #else
01757 TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
01758 #endif
01759 TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
01760
01761 #ifdef ROUND_TYPE_SIZE
01762 if (TYPE_SIZE (type) != 0)
01763 {
01764 tree tmp
01765 = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
01766
01767
01768
01769 if (simple_cst_equal (TYPE_SIZE (type), tmp) != 1)
01770 TYPE_SIZE_UNIT (type) = NULL;
01771
01772 TYPE_SIZE (type) = tmp;
01773 }
01774 #endif
01775
01776 TYPE_MODE (type) = BLKmode;
01777 if (TYPE_SIZE (type) != 0
01778 #ifdef MEMBER_TYPE_FORCES_BLK
01779 && ! MEMBER_TYPE_FORCES_BLK (type, VOIDmode)
01780 #endif
01781
01782
01783 && (TYPE_MODE (TREE_TYPE (type)) != BLKmode
01784 || TYPE_NO_FORCE_BLK (TREE_TYPE (type))))
01785 {
01786
01787 if (simple_cst_equal (TYPE_SIZE (type),
01788 TYPE_SIZE (TREE_TYPE (type))))
01789 TYPE_MODE (type) = TYPE_MODE (TREE_TYPE (type));
01790 else
01791 TYPE_MODE (type)
01792 = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
01793
01794 if (TYPE_MODE (type) != BLKmode
01795 && STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
01796 && TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type))
01797 && TYPE_MODE (type) != BLKmode)
01798 {
01799 TYPE_NO_FORCE_BLK (type) = 1;
01800 TYPE_MODE (type) = BLKmode;
01801 }
01802 }
01803 break;
01804 }
01805
01806 case RECORD_TYPE:
01807 case UNION_TYPE:
01808 case QUAL_UNION_TYPE:
01809 {
01810 tree field;
01811 record_layout_info rli;
01812
01813
01814 rli = start_record_layout (type);
01815
01816
01817
01818
01819 if (TREE_CODE (type) == QUAL_UNION_TYPE)
01820 TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));
01821
01822
01823 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
01824 place_field (rli, field);
01825
01826 if (TREE_CODE (type) == QUAL_UNION_TYPE)
01827 TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));
01828
01829 if (lang_adjust_rli)
01830 (*lang_adjust_rli) (rli);
01831
01832
01833 finish_record_layout (rli, true);
01834 #ifdef SGI_MONGOOSE
01835 assign_field_ids(type);
01836 #endif
01837 }
01838 break;
01839
01840 case SET_TYPE:
01841 if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST
01842 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST)
01843 abort ();
01844 else
01845 {
01846 #ifndef SET_WORD_SIZE
01847 #define SET_WORD_SIZE BITS_PER_WORD
01848 #endif
01849 unsigned int alignment
01850 = set_alignment ? set_alignment : SET_WORD_SIZE;
01851 int size_in_bits
01852 = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
01853 - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1);
01854 int rounded_size
01855 = ((size_in_bits + alignment - 1) / alignment) * alignment;
01856
01857 if (rounded_size > (int) alignment)
01858 TYPE_MODE (type) = BLKmode;
01859 else
01860 TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);
01861
01862 TYPE_SIZE (type) = bitsize_int (rounded_size);
01863 TYPE_SIZE_UNIT (type) = size_int (rounded_size / BITS_PER_UNIT);
01864 TYPE_ALIGN (type) = alignment;
01865 TYPE_USER_ALIGN (type) = 0;
01866 TYPE_PRECISION (type) = size_in_bits;
01867 }
01868 break;
01869
01870 case FILE_TYPE:
01871
01872
01873 TYPE_ALIGN (type) = BIGGEST_ALIGNMENT;
01874 TYPE_USER_ALIGN (type) = 0;
01875 TYPE_MODE (type) = BLKmode;
01876 break;
01877
01878 default:
01879 abort ();
01880 }
01881
01882
01883
01884
01885 if (TREE_CODE (type) != RECORD_TYPE
01886 && TREE_CODE (type) != UNION_TYPE
01887 && TREE_CODE (type) != QUAL_UNION_TYPE)
01888 finalize_type_size (type);
01889
01890
01891
01892 if (! sizetype_set)
01893 early_type_list = tree_cons (NULL_TREE, type, early_type_list);
01894
01895
01896
01897
01898
01899
01900 if (AGGREGATE_TYPE_P (type) && TYPE_ALIAS_SET_KNOWN_P (type))
01901 TYPE_ALIAS_SET (type) = 0;
01902 }
01903
01904
01905
01906 tree
01907 make_signed_type (precision)
01908 int precision;
01909 {
01910 tree type = make_node (INTEGER_TYPE);
01911
01912 TYPE_PRECISION (type) = precision;
01913
01914 fixup_signed_type (type);
01915 return type;
01916 }
01917
01918
01919
01920 tree
01921 make_unsigned_type (precision)
01922 int precision;
01923 {
01924 tree type = make_node (INTEGER_TYPE);
01925
01926 TYPE_PRECISION (type) = precision;
01927
01928 fixup_unsigned_type (type);
01929 return type;
01930 }
01931
01932
01933
01934
01935 void
01936 initialize_sizetypes ()
01937 {
01938 tree t = make_node (INTEGER_TYPE);
01939
01940
01941
01942 integer_type_node = t;
01943
01944 TYPE_MODE (t) = SImode;
01945 TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode);
01946 TYPE_USER_ALIGN (t) = 0;
01947 TYPE_SIZE (t) = build_int_2 (GET_MODE_BITSIZE (SImode), 0);
01948 TYPE_SIZE_UNIT (t) = build_int_2 (GET_MODE_SIZE (SImode), 0);
01949 TREE_UNSIGNED (t) = 1;
01950 TYPE_PRECISION (t) = GET_MODE_BITSIZE (SImode);
01951 TYPE_MIN_VALUE (t) = build_int_2 (0, 0);
01952 TYPE_IS_SIZETYPE (t) = 1;
01953
01954
01955
01956 TYPE_MAX_VALUE (t) = build_int_2 (1000, 0);
01957
01958
01959
01960 sizetype = t;
01961 bitsizetype = copy_node (t);
01962 integer_type_node = 0;
01963 }
01964
01965
01966
01967
01968 void
01969 set_sizetype (type)
01970 tree type;
01971 {
01972 int oprecision = TYPE_PRECISION (type);
01973
01974
01975
01976
01977 int precision = MIN (oprecision + BITS_PER_UNIT_LOG + 1,
01978 2 * HOST_BITS_PER_WIDE_INT);
01979 unsigned int i;
01980 tree t;
01981
01982 if (sizetype_set)
01983 abort ();
01984
01985
01986 sizetype = copy_node (type);
01987 TYPE_DOMAIN (sizetype) = type;
01988 TYPE_IS_SIZETYPE (sizetype) = 1;
01989 bitsizetype = make_node (INTEGER_TYPE);
01990 TYPE_NAME (bitsizetype) = TYPE_NAME (type);
01991 TYPE_PRECISION (bitsizetype) = precision;
01992 TYPE_IS_SIZETYPE (bitsizetype) = 1;
01993
01994 if (TREE_UNSIGNED (type))
01995 fixup_unsigned_type (bitsizetype);
01996 else
01997 fixup_signed_type (bitsizetype);
01998
01999 layout_type (bitsizetype);
02000
02001 if (TREE_UNSIGNED (type))
02002 {
02003 usizetype = sizetype;
02004 ubitsizetype = bitsizetype;
02005 ssizetype = copy_node (make_signed_type (oprecision));
02006 sbitsizetype = copy_node (make_signed_type (precision));
02007 }
02008 else
02009 {
02010 ssizetype = sizetype;
02011 sbitsizetype = bitsizetype;
02012 usizetype = copy_node (make_unsigned_type (oprecision));
02013 ubitsizetype = copy_node (make_unsigned_type (precision));
02014 }
02015
02016 TYPE_NAME (bitsizetype) = get_identifier ("bit_size_type");
02017
02018
02019 for (i = 0; i < ARRAY_SIZE (sizetype_tab); i++)
02020 {
02021 TYPE_IS_SIZETYPE (sizetype_tab[i]) = 1;
02022 TYPE_MAIN_VARIANT (sizetype_tab[i]) = sizetype_tab[i];
02023 TYPE_NEXT_VARIANT (sizetype_tab[i]) = 0;
02024 TYPE_POINTER_TO (sizetype_tab[i]) = 0;
02025 TYPE_REFERENCE_TO (sizetype_tab[i]) = 0;
02026 }
02027
02028
02029
02030 for (t = early_type_list; t != 0; t = TREE_CHAIN (t))
02031 {
02032 if (TREE_CODE (TREE_VALUE (t)) != INTEGER_TYPE)
02033 abort ();
02034
02035 TREE_TYPE (TYPE_SIZE (TREE_VALUE (t))) = bitsizetype;
02036 TREE_TYPE (TYPE_SIZE_UNIT (TREE_VALUE (t))) = sizetype;
02037 }
02038
02039 early_type_list = 0;
02040 sizetype_set = 1;
02041 }
02042
02043
02044
02045
02046
02047
02048 void
02049 fixup_signed_type (type)
02050 tree type;
02051 {
02052 int precision = TYPE_PRECISION (type);
02053
02054
02055
02056
02057 if (precision > HOST_BITS_PER_WIDE_INT * 2)
02058 precision = HOST_BITS_PER_WIDE_INT * 2;
02059
02060 TYPE_MIN_VALUE (type)
02061 = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
02062 ? 0 : (HOST_WIDE_INT) (-1) << (precision - 1)),
02063 (((HOST_WIDE_INT) (-1)
02064 << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
02065 ? precision - HOST_BITS_PER_WIDE_INT - 1
02066 : 0))));
02067 TYPE_MAX_VALUE (type)
02068 = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
02069 ? -1 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
02070 (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
02071 ? (((HOST_WIDE_INT) 1
02072 << (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
02073 : 0));
02074
02075 TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
02076 TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
02077
02078
02079 layout_type (type);
02080 }
02081
02082
02083
02084
02085
02086 void
02087 fixup_unsigned_type (type)
02088 tree type;
02089 {
02090 int precision = TYPE_PRECISION (type);
02091
02092
02093
02094
02095 if (precision > HOST_BITS_PER_WIDE_INT * 2)
02096 precision = HOST_BITS_PER_WIDE_INT * 2;
02097
02098 TYPE_MIN_VALUE (type) = build_int_2 (0, 0);
02099 TYPE_MAX_VALUE (type)
02100 = build_int_2 (precision - HOST_BITS_PER_WIDE_INT >= 0
02101 ? -1 : ((HOST_WIDE_INT) 1 << precision) - 1,
02102 precision - HOST_BITS_PER_WIDE_INT > 0
02103 ? ((unsigned HOST_WIDE_INT) ~0
02104 >> (HOST_BITS_PER_WIDE_INT
02105 - (precision - HOST_BITS_PER_WIDE_INT)))
02106 : 0);
02107 TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
02108 TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
02109
02110
02111 layout_type (type);
02112 }
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129 enum machine_mode
02130 get_best_mode (bitsize, bitpos, align, largest_mode, volatilep)
02131 int bitsize, bitpos;
02132 unsigned int align;
02133 enum machine_mode largest_mode;
02134 int volatilep;
02135 {
02136 enum machine_mode mode;
02137 unsigned int unit = 0;
02138
02139
02140 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
02141 mode = GET_MODE_WIDER_MODE (mode))
02142 {
02143 unit = GET_MODE_BITSIZE (mode);
02144 if ((bitpos % unit) + bitsize <= unit)
02145 break;
02146 }
02147
02148 if (mode == VOIDmode
02149
02150
02151
02152
02153
02154
02155
02156 || MIN (unit, BIGGEST_ALIGNMENT) > align
02157 || (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode)))
02158 return VOIDmode;
02159
02160 if (SLOW_BYTE_ACCESS && ! volatilep)
02161 {
02162 enum machine_mode wide_mode = VOIDmode, tmode;
02163
02164 for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); tmode != VOIDmode;
02165 tmode = GET_MODE_WIDER_MODE (tmode))
02166 {
02167 unit = GET_MODE_BITSIZE (tmode);
02168 if (bitpos / unit == (bitpos + bitsize - 1) / unit
02169 && unit <= BITS_PER_WORD
02170 && unit <= MIN (align, BIGGEST_ALIGNMENT)
02171 && (largest_mode == VOIDmode
02172 || unit <= GET_MODE_BITSIZE (largest_mode)))
02173 wide_mode = tmode;
02174 }
02175
02176 if (wide_mode != VOIDmode)
02177 return wide_mode;
02178 }
02179
02180 return mode;
02181 }
02182
02183 #include "gt-stor-layout.h"