2005-05-19 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / fortran / trans-common.c
blobd164fe3494065a90882b517ea242bca4ce0760d1
1 /* Common block and equivalence list handling
2 Copyright (C) 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Canqun Yang <canqun@nudt.edu.cn>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 /* The core algorithm is based on Andy Vaught's g95 tree. Also the
23 way to build UNION_TYPE is borrowed from Richard Henderson.
25 Transform common blocks. An integral part of this is processing
26 equivalence variables. Equivalenced variables that are not in a
27 common block end up in a private block of their own.
29 Each common block or local equivalence list is declared as a union.
30 Variables within the block are represented as a field within the
31 block with the proper offset.
33 So if two variables are equivalenced, they just point to a common
34 area in memory.
36 Mathematically, laying out an equivalence block is equivalent to
37 solving a linear system of equations. The matrix is usually a
38 sparse matrix in which each row contains all zero elements except
39 for a +1 and a -1, a sort of a generalized Vandermonde matrix. The
40 matrix is usually block diagonal. The system can be
41 overdetermined, underdetermined or have a unique solution. If the
42 system is inconsistent, the program is not standard conforming.
43 The solution vector is integral, since all of the pivots are +1 or -1.
45 How we lay out an equivalence block is a little less complicated.
46 In an equivalence list with n elements, there are n-1 conditions to
47 be satisfied. The conditions partition the variables into what we
48 will call segments. If A and B are equivalenced then A and B are
49 in the same segment. If B and C are equivalenced as well, then A,
50 B and C are in a segment and so on. Each segment is a block of
51 memory that has one or more variables equivalenced in some way. A
52 common block is made up of a series of segments that are joined one
53 after the other. In the linear system, a segment is a block
54 diagonal.
56 To lay out a segment we first start with some variable and
57 determine its length. The first variable is assumed to start at
58 offset one and extends to however long it is. We then traverse the
59 list of equivalences to find an unused condition that involves at
60 least one of the variables currently in the segment.
62 Each equivalence condition amounts to the condition B+b=C+c where B
63 and C are the offsets of the B and C variables, and b and c are
64 constants which are nonzero for array elements, substrings or
65 structure components. So for
67 EQUIVALENCE(B(2), C(3))
68 we have
69 B + 2*size of B's elements = C + 3*size of C's elements.
71 If B and C are known we check to see if the condition already
72 holds. If B is known we can solve for C. Since we know the length
73 of C, we can see if the minimum and maximum extents of the segment
74 are affected. Eventually, we make a full pass through the
75 equivalence list without finding any new conditions and the segment
76 is fully specified.
78 At this point, the segment is added to the current common block.
79 Since we know the minimum extent of the segment, everything in the
80 segment is translated to its position in the common block. The
81 usual case here is that there are no equivalence statements and the
82 common block is series of segments with one variable each, which is
83 a diagonal matrix in the matrix formulation.
85 Each segment is described by a chain of segment_info structures. Each
86 segment_info structure describes the extents of a single varible within
87 the segment. This list is maintained in the order the elements are
88 positioned withing the segment. If two elements have the same starting
89 offset the smaller will come first. If they also have the same size their
90 ordering is undefined.
92 Once all common blocks have been created, the list of equivalences
93 is examined for still-unused equivalence conditions. We create a
94 block for each merged equivalence list. */
96 #include "config.h"
97 #include "system.h"
98 #include "coretypes.h"
99 #include "tree.h"
100 #include "toplev.h"
101 #include "tm.h"
102 #include "gfortran.h"
103 #include "trans.h"
104 #include "trans-types.h"
105 #include "trans-const.h"
108 /* Holds a single variable in a equivalence set. */
109 typedef struct segment_info
111 gfc_symbol *sym;
112 HOST_WIDE_INT offset;
113 HOST_WIDE_INT length;
114 /* This will contain the field type until the field is created. */
115 tree field;
116 struct segment_info *next;
117 } segment_info;
119 static segment_info * current_segment;
120 static gfc_namespace *gfc_common_ns = NULL;
122 #define BLANK_COMMON_NAME "__BLNK__"
124 /* Make a segment_info based on a symbol. */
126 static segment_info *
127 get_segment_info (gfc_symbol * sym, HOST_WIDE_INT offset)
129 segment_info *s;
131 /* Make sure we've got the character length. */
132 if (sym->ts.type == BT_CHARACTER)
133 gfc_conv_const_charlen (sym->ts.cl);
135 /* Create the segment_info and fill it in. */
136 s = (segment_info *) gfc_getmem (sizeof (segment_info));
137 s->sym = sym;
138 /* We will use this type when building the segment aggregate type. */
139 s->field = gfc_sym_type (sym);
140 s->length = int_size_in_bytes (s->field);
141 s->offset = offset;
143 return s;
146 /* Add combine segment V and segment LIST. */
148 static segment_info *
149 add_segments (segment_info *list, segment_info *v)
151 segment_info *s;
152 segment_info *p;
153 segment_info *next;
155 p = NULL;
156 s = list;
158 while (v)
160 /* Find the location of the new element. */
161 while (s)
163 if (v->offset < s->offset)
164 break;
165 if (v->offset == s->offset
166 && v->length <= s->length)
167 break;
169 p = s;
170 s = s->next;
173 /* Insert the new element in between p and s. */
174 next = v->next;
175 v->next = s;
176 if (p == NULL)
177 list = v;
178 else
179 p->next = v;
181 p = v;
182 v = next;
185 return list;
188 /* Construct mangled common block name from symbol name. */
190 static tree
191 gfc_sym_mangled_common_id (const char *name)
193 int has_underscore;
194 char mangled_name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
196 if (strcmp (name, BLANK_COMMON_NAME) == 0)
197 return get_identifier (name);
199 if (gfc_option.flag_underscoring)
201 has_underscore = strchr (name, '_') != 0;
202 if (gfc_option.flag_second_underscore && has_underscore)
203 snprintf (mangled_name, sizeof mangled_name, "%s__", name);
204 else
205 snprintf (mangled_name, sizeof mangled_name, "%s_", name);
207 return get_identifier (mangled_name);
209 else
210 return get_identifier (name);
214 /* Build a field declaration for a common variable or a local equivalence
215 object. */
217 static void
218 build_field (segment_info *h, tree union_type, record_layout_info rli)
220 tree field;
221 tree name;
222 HOST_WIDE_INT offset = h->offset;
223 unsigned HOST_WIDE_INT desired_align, known_align;
225 name = get_identifier (h->sym->name);
226 field = build_decl (FIELD_DECL, name, h->field);
227 gfc_set_decl_location (field, &h->sym->declared_at);
228 known_align = (offset & -offset) * BITS_PER_UNIT;
229 if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
230 known_align = BIGGEST_ALIGNMENT;
232 desired_align = update_alignment_for_field (rli, field, known_align);
233 if (desired_align > known_align)
234 DECL_PACKED (field) = 1;
236 DECL_FIELD_CONTEXT (field) = union_type;
237 DECL_FIELD_OFFSET (field) = size_int (offset);
238 DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
239 SET_DECL_OFFSET_ALIGN (field, known_align);
241 rli->offset = size_binop (MAX_EXPR, rli->offset,
242 size_binop (PLUS_EXPR,
243 DECL_FIELD_OFFSET (field),
244 DECL_SIZE_UNIT (field)));
245 /* If this field is assigned to a label, we create another two variables.
246 One will hold the address of taget label or format label. The other will
247 hold the length of format label string. */
248 if (h->sym->attr.assign)
250 tree len;
251 tree addr;
253 gfc_allocate_lang_decl (field);
254 GFC_DECL_ASSIGN (field) = 1;
255 len = gfc_create_var_np (gfc_charlen_type_node,h->sym->name);
256 addr = gfc_create_var_np (pvoid_type_node, h->sym->name);
257 TREE_STATIC (len) = 1;
258 TREE_STATIC (addr) = 1;
259 DECL_INITIAL (len) = build_int_cst (NULL_TREE, -2);
260 gfc_set_decl_location (len, &h->sym->declared_at);
261 gfc_set_decl_location (addr, &h->sym->declared_at);
262 GFC_DECL_STRING_LEN (field) = pushdecl_top_level (len);
263 GFC_DECL_ASSIGN_ADDR (field) = pushdecl_top_level (addr);
266 h->field = field;
270 /* Get storage for local equivalence. */
272 static tree
273 build_equiv_decl (tree union_type, bool is_init)
275 tree decl;
276 char name[15];
277 static int serial = 0;
279 if (is_init)
281 decl = gfc_create_var (union_type, "equiv");
282 TREE_STATIC (decl) = 1;
283 return decl;
286 snprintf (name, sizeof (name), "equiv.%d", serial++);
287 decl = build_decl (VAR_DECL, get_identifier (name), union_type);
288 DECL_ARTIFICIAL (decl) = 1;
289 DECL_IGNORED_P (decl) = 1;
291 if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)))
292 TREE_STATIC (decl) = 1;
294 TREE_ADDRESSABLE (decl) = 1;
295 TREE_USED (decl) = 1;
297 /* The source location has been lost, and doesn't really matter.
298 We need to set it to something though. */
299 gfc_set_decl_location (decl, &gfc_current_locus);
301 gfc_add_decl_to_function (decl);
303 return decl;
307 /* Get storage for common block. */
309 static tree
310 build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
312 gfc_symbol *common_sym;
313 tree decl;
315 /* Create a namespace to store symbols for common blocks. */
316 if (gfc_common_ns == NULL)
317 gfc_common_ns = gfc_get_namespace (NULL, 0);
319 gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
320 decl = common_sym->backend_decl;
322 /* Update the size of this common block as needed. */
323 if (decl != NULL_TREE)
325 tree size = TYPE_SIZE_UNIT (union_type);
326 if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
328 /* Named common blocks of the same name shall be of the same size
329 in all scoping units of a program in which they appear, but
330 blank common blocks may be of different sizes. */
331 if (strcmp (com->name, BLANK_COMMON_NAME))
332 gfc_warning ("Named COMMON block '%s' at %L shall be of the "
333 "same size", com->name, &com->where);
334 DECL_SIZE_UNIT (decl) = size;
338 /* If this common block has been declared in a previous program unit,
339 and either it is already initialized or there is no new initialization
340 for it, just return. */
341 if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
342 return decl;
344 /* If there is no backend_decl for the common block, build it. */
345 if (decl == NULL_TREE)
347 decl = build_decl (VAR_DECL, get_identifier (com->name), union_type);
348 SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com->name));
349 TREE_PUBLIC (decl) = 1;
350 TREE_STATIC (decl) = 1;
351 DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
352 DECL_USER_ALIGN (decl) = 0;
354 gfc_set_decl_location (decl, &com->where);
356 /* Place the back end declaration for this common block in
357 GLOBAL_BINDING_LEVEL. */
358 common_sym->backend_decl = pushdecl_top_level (decl);
361 /* Has no initial values. */
362 if (!is_init)
364 DECL_INITIAL (decl) = NULL_TREE;
365 DECL_COMMON (decl) = 1;
366 DECL_DEFER_OUTPUT (decl) = 1;
368 else
370 DECL_INITIAL (decl) = error_mark_node;
371 DECL_COMMON (decl) = 0;
372 DECL_DEFER_OUTPUT (decl) = 0;
374 return decl;
378 /* Declare memory for the common block or local equivalence, and create
379 backend declarations for all of the elements. */
381 static void
382 create_common (gfc_common_head *com, segment_info * head, bool saw_equiv)
384 segment_info *s, *next_s;
385 tree union_type;
386 tree *field_link;
387 record_layout_info rli;
388 tree decl;
389 bool is_init = false;
391 /* Declare the variables inside the common block.
392 If the current common block contains any equivalence object, then
393 make a UNION_TYPE node, otherwise RECORD_TYPE. This will let the
394 alias analyzer work well when there is no address overlapping for
395 common variables in the current common block. */
396 if (saw_equiv)
397 union_type = make_node (UNION_TYPE);
398 else
399 union_type = make_node (RECORD_TYPE);
401 rli = start_record_layout (union_type);
402 field_link = &TYPE_FIELDS (union_type);
404 for (s = head; s; s = s->next)
406 build_field (s, union_type, rli);
408 /* Link the field into the type. */
409 *field_link = s->field;
410 field_link = &TREE_CHAIN (s->field);
412 /* Has initial value. */
413 if (s->sym->value)
414 is_init = true;
416 finish_record_layout (rli, true);
418 if (com)
419 decl = build_common_decl (com, union_type, is_init);
420 else
421 decl = build_equiv_decl (union_type, is_init);
423 if (is_init)
425 tree list, ctor, tmp;
426 HOST_WIDE_INT offset = 0;
428 list = NULL_TREE;
429 for (s = head; s; s = s->next)
431 if (s->sym->value)
433 if (s->offset < offset)
435 /* We have overlapping initializers. It could either be
436 partially initialized arrays (legal), or the user
437 specified multiple initial values (illegal).
438 We don't implement this yet, so bail out. */
439 gfc_todo_error ("Initialization of overlapping variables");
441 /* Add the initializer for this field. */
442 tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
443 TREE_TYPE (s->field), s->sym->attr.dimension,
444 s->sym->attr.pointer || s->sym->attr.allocatable);
445 list = tree_cons (s->field, tmp, list);
446 offset = s->offset + s->length;
449 gcc_assert (list);
450 ctor = build1 (CONSTRUCTOR, union_type, nreverse(list));
451 TREE_CONSTANT (ctor) = 1;
452 TREE_INVARIANT (ctor) = 1;
453 TREE_STATIC (ctor) = 1;
454 DECL_INITIAL (decl) = ctor;
456 #ifdef ENABLE_CHECKING
457 for (tmp = CONSTRUCTOR_ELTS (ctor); tmp; tmp = TREE_CHAIN (tmp))
458 gcc_assert (TREE_CODE (TREE_PURPOSE (tmp)) == FIELD_DECL);
459 #endif
462 /* Build component reference for each variable. */
463 for (s = head; s; s = next_s)
465 s->sym->backend_decl = build3 (COMPONENT_REF, TREE_TYPE (s->field),
466 decl, s->field, NULL_TREE);
468 next_s = s->next;
469 gfc_free (s);
474 /* Given a symbol, find it in the current segment list. Returns NULL if
475 not found. */
477 static segment_info *
478 find_segment_info (gfc_symbol *symbol)
480 segment_info *n;
482 for (n = current_segment; n; n = n->next)
484 if (n->sym == symbol)
485 return n;
488 return NULL;
492 /* Given an expression node, make sure it is a constant integer and return
493 the mpz_t value. */
495 static mpz_t *
496 get_mpz (gfc_expr *e)
499 if (e->expr_type != EXPR_CONSTANT)
500 gfc_internal_error ("get_mpz(): Not an integer constant");
502 return &e->value.integer;
506 /* Given an array specification and an array reference, figure out the
507 array element number (zero based). Bounds and elements are guaranteed
508 to be constants. If something goes wrong we generate an error and
509 return zero. */
511 static HOST_WIDE_INT
512 element_number (gfc_array_ref *ar)
514 mpz_t multiplier, offset, extent, n;
515 gfc_array_spec *as;
516 HOST_WIDE_INT i, rank;
518 as = ar->as;
519 rank = as->rank;
520 mpz_init_set_ui (multiplier, 1);
521 mpz_init_set_ui (offset, 0);
522 mpz_init (extent);
523 mpz_init (n);
525 for (i = 0; i < rank; i++)
527 if (ar->dimen_type[i] != DIMEN_ELEMENT)
528 gfc_internal_error ("element_number(): Bad dimension type");
530 mpz_sub (n, *get_mpz (ar->start[i]), *get_mpz (as->lower[i]));
532 mpz_mul (n, n, multiplier);
533 mpz_add (offset, offset, n);
535 mpz_sub (extent, *get_mpz (as->upper[i]), *get_mpz (as->lower[i]));
536 mpz_add_ui (extent, extent, 1);
538 if (mpz_sgn (extent) < 0)
539 mpz_set_ui (extent, 0);
541 mpz_mul (multiplier, multiplier, extent);
544 i = mpz_get_ui (offset);
546 mpz_clear (multiplier);
547 mpz_clear (offset);
548 mpz_clear (extent);
549 mpz_clear (n);
551 return i;
555 /* Given a single element of an equivalence list, figure out the offset
556 from the base symbol. For simple variables or full arrays, this is
557 simply zero. For an array element we have to calculate the array
558 element number and multiply by the element size. For a substring we
559 have to calculate the further reference. */
561 static HOST_WIDE_INT
562 calculate_offset (gfc_expr *e)
564 HOST_WIDE_INT n, element_size, offset;
565 gfc_typespec *element_type;
566 gfc_ref *reference;
568 offset = 0;
569 element_type = &e->symtree->n.sym->ts;
571 for (reference = e->ref; reference; reference = reference->next)
572 switch (reference->type)
574 case REF_ARRAY:
575 switch (reference->u.ar.type)
577 case AR_FULL:
578 break;
580 case AR_ELEMENT:
581 n = element_number (&reference->u.ar);
582 if (element_type->type == BT_CHARACTER)
583 gfc_conv_const_charlen (element_type->cl);
584 element_size =
585 int_size_in_bytes (gfc_typenode_for_spec (element_type));
586 offset += n * element_size;
587 break;
589 default:
590 gfc_error ("Bad array reference at %L", &e->where);
592 break;
593 case REF_SUBSTRING:
594 if (reference->u.ss.start != NULL)
595 offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
596 break;
597 default:
598 gfc_error ("Illegal reference type at %L as EQUIVALENCE object",
599 &e->where);
601 return offset;
605 /* Add a new segment_info structure to the current segment. eq1 is already
606 in the list, eq2 is not. */
608 static void
609 new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
611 HOST_WIDE_INT offset1, offset2;
612 segment_info *a;
614 offset1 = calculate_offset (eq1->expr);
615 offset2 = calculate_offset (eq2->expr);
617 a = get_segment_info (eq2->expr->symtree->n.sym,
618 v->offset + offset1 - offset2);
620 current_segment = add_segments (current_segment, a);
624 /* Given two equivalence structures that are both already in the list, make
625 sure that this new condition is not violated, generating an error if it
626 is. */
628 static void
629 confirm_condition (segment_info *s1, gfc_equiv *eq1, segment_info *s2,
630 gfc_equiv *eq2)
632 HOST_WIDE_INT offset1, offset2;
634 offset1 = calculate_offset (eq1->expr);
635 offset2 = calculate_offset (eq2->expr);
637 if (s1->offset + offset1 != s2->offset + offset2)
638 gfc_error ("Inconsistent equivalence rules involving '%s' at %L and "
639 "'%s' at %L", s1->sym->name, &s1->sym->declared_at,
640 s2->sym->name, &s2->sym->declared_at);
644 /* Process a new equivalence condition. eq1 is know to be in segment f.
645 If eq2 is also present then confirm that the condition holds.
646 Otherwise add a new variable to the segment list. */
648 static void
649 add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
651 segment_info *n;
653 n = find_segment_info (eq2->expr->symtree->n.sym);
655 if (n == NULL)
656 new_condition (f, eq1, eq2);
657 else
658 confirm_condition (f, eq1, n, eq2);
662 /* Given a segment element, search through the equivalence lists for unused
663 conditions that involve the symbol. Add these rules to the segment. Only
664 checks for rules involving the first symbol in the equivalence set. */
666 static bool
667 find_equivalence (segment_info *n)
669 gfc_equiv *e1, *e2, *eq, *other;
670 bool found;
672 found = FALSE;
673 for (e1 = n->sym->ns->equiv; e1; e1 = e1->next)
675 other = NULL;
676 for (e2 = e1->eq; e2; e2 = e2->eq)
678 if (e2->used)
679 continue;
681 if (e1->expr->symtree->n.sym == n->sym)
683 eq = e1;
684 other = e2;
686 else if (e2->expr->symtree->n.sym == n->sym)
688 eq = e2;
689 other = e1;
691 else
692 eq = NULL;
694 if (eq)
696 add_condition (n, eq, other);
697 eq->used = 1;
698 found = TRUE;
699 /* If this symbol is the first in the chain we may find other
700 matches. Otherwise we can skip to the next equivalence. */
701 if (eq == e2)
702 break;
706 return found;
710 /* Add all symbols equivalenced within a segment. We need to scan the
711 segment list multiple times to include indirect equivalences. */
713 static void
714 add_equivalences (bool *saw_equiv)
716 segment_info *f;
717 bool more;
719 more = TRUE;
720 while (more)
722 more = FALSE;
723 for (f = current_segment; f; f = f->next)
725 if (!f->sym->equiv_built)
727 f->sym->equiv_built = 1;
728 more = find_equivalence (f);
729 if (more)
730 *saw_equiv = true;
737 /* Returns the offset necessary to properly align the current equivalence.
738 Sets *palign to the required alignment. */
740 static HOST_WIDE_INT
741 align_segment (unsigned HOST_WIDE_INT * palign)
743 segment_info *s;
744 unsigned HOST_WIDE_INT offset;
745 unsigned HOST_WIDE_INT max_align;
746 unsigned HOST_WIDE_INT this_align;
747 unsigned HOST_WIDE_INT this_offset;
749 max_align = 1;
750 offset = 0;
751 for (s = current_segment; s; s = s->next)
753 this_align = TYPE_ALIGN_UNIT (s->field);
754 if (s->offset & (this_align - 1))
756 /* Field is misaligned. */
757 this_offset = this_align - ((s->offset + offset) & (this_align - 1));
758 if (this_offset & (max_align - 1))
760 /* Aligning this field would misalign a previous field. */
761 gfc_error ("The equivalence set for variable '%s' "
762 "declared at %L violates alignment requirents",
763 s->sym->name, &s->sym->declared_at);
765 offset += this_offset;
767 max_align = this_align;
769 if (palign)
770 *palign = max_align;
771 return offset;
775 /* Adjust segment offsets by the given amount. */
777 static void
778 apply_segment_offset (segment_info * s, HOST_WIDE_INT offset)
780 for (; s; s = s->next)
781 s->offset += offset;
785 /* Lay out a symbol in a common block. If the symbol has already been seen
786 then check the location is consistent. Otherwise create segments
787 for that symbol and all the symbols equivalenced with it. */
789 /* Translate a single common block. */
791 static void
792 translate_common (gfc_common_head *common, gfc_symbol *var_list)
794 gfc_symbol *sym;
795 segment_info *s;
796 segment_info *common_segment;
797 HOST_WIDE_INT offset;
798 HOST_WIDE_INT current_offset;
799 unsigned HOST_WIDE_INT align;
800 unsigned HOST_WIDE_INT max_align;
801 bool saw_equiv;
803 common_segment = NULL;
804 current_offset = 0;
805 max_align = 1;
806 saw_equiv = false;
808 /* Add symbols to the segment. */
809 for (sym = var_list; sym; sym = sym->common_next)
811 if (sym->equiv_built)
813 /* Symbol has already been added via an equivalence. */
814 current_segment = common_segment;
815 s = find_segment_info (sym);
817 /* Ensure the current location is properly aligned. */
818 align = TYPE_ALIGN_UNIT (s->field);
819 current_offset = (current_offset + align - 1) &~ (align - 1);
821 /* Verify that it ended up where we expect it. */
822 if (s->offset != current_offset)
824 gfc_error ("Equivalence for '%s' does not match ordering of "
825 "COMMON '%s' at %L", sym->name,
826 common->name, &common->where);
829 else
831 /* A symbol we haven't seen before. */
832 s = current_segment = get_segment_info (sym, current_offset);
834 /* Add all objects directly or indirectly equivalenced with this
835 symbol. */
836 add_equivalences (&saw_equiv);
838 if (current_segment->offset < 0)
839 gfc_error ("The equivalence set for '%s' cause an invalid "
840 "extension to COMMON '%s' at %L", sym->name,
841 common->name, &common->where);
843 offset = align_segment (&align);
845 if (offset & (max_align - 1))
847 /* The required offset conflicts with previous alignment
848 requirements. Insert padding immediately before this
849 segment. */
850 gfc_warning ("Padding of %d bytes required before '%s' in "
851 "COMMON '%s' at %L", (int)offset, s->sym->name,
852 common->name, &common->where);
854 else
856 /* Offset the whole common block. */
857 apply_segment_offset (common_segment, offset);
860 /* Apply the offset to the new segments. */
861 apply_segment_offset (current_segment, offset);
862 current_offset += offset;
863 if (max_align < align)
864 max_align = align;
866 /* Add the new segments to the common block. */
867 common_segment = add_segments (common_segment, current_segment);
870 /* The offset of the next common variable. */
871 current_offset += s->length;
874 if (common_segment->offset != 0)
876 gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start",
877 common->name, &common->where, (int)common_segment->offset);
880 create_common (common, common_segment, saw_equiv);
884 /* Create a new block for each merged equivalence list. */
886 static void
887 finish_equivalences (gfc_namespace *ns)
889 gfc_equiv *z, *y;
890 gfc_symbol *sym;
891 HOST_WIDE_INT offset;
892 unsigned HOST_WIDE_INT align;
893 bool dummy;
895 for (z = ns->equiv; z; z = z->next)
896 for (y = z->eq; y; y = y->eq)
898 if (y->used)
899 continue;
900 sym = z->expr->symtree->n.sym;
901 current_segment = get_segment_info (sym, 0);
903 /* All objects directly or indirectly equivalenced with this symbol. */
904 add_equivalences (&dummy);
906 /* Align the block. */
907 offset = align_segment (&align);
909 /* Ensure all offsets are positive. */
910 offset -= current_segment->offset & ~(align - 1);
912 apply_segment_offset (current_segment, offset);
914 /* Create the decl. */
915 create_common (NULL, current_segment, true);
916 break;
921 /* Work function for translating a named common block. */
923 static void
924 named_common (gfc_symtree *st)
926 translate_common (st->n.common, st->n.common->head);
930 /* Translate the common blocks in a namespace. Unlike other variables,
931 these have to be created before code, because the backend_decl depends
932 on the rest of the common block. */
934 void
935 gfc_trans_common (gfc_namespace *ns)
937 gfc_common_head *c;
939 /* Translate the blank common block. */
940 if (ns->blank_common.head != NULL)
942 c = gfc_get_common_head ();
943 /* We've lost the real location, so use the location of the
944 enclosing procedure. */
945 c->where = ns->proc_name->declared_at;
946 strcpy (c->name, BLANK_COMMON_NAME);
947 translate_common (c, ns->blank_common.head);
950 /* Translate all named common blocks. */
951 gfc_traverse_symtree (ns->common_root, named_common);
953 /* Commit the newly created symbols for common blocks. */
954 gfc_commit_symbols ();
956 /* Translate local equivalence. */
957 finish_equivalences (ns);