Merge from the pain train
[official-gcc.git] / gcc / fortran / trans-common.c
blob35ea80120344b17f4512457baebb82c875736dea
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 h->field = field;
249 /* Get storage for local equivalence. */
251 static tree
252 build_equiv_decl (tree union_type, bool is_init)
254 tree decl;
256 if (is_init)
258 decl = gfc_create_var (union_type, "equiv");
259 TREE_STATIC (decl) = 1;
260 return decl;
263 decl = build_decl (VAR_DECL, NULL, union_type);
264 DECL_ARTIFICIAL (decl) = 1;
266 DECL_COMMON (decl) = 1;
268 TREE_ADDRESSABLE (decl) = 1;
269 TREE_USED (decl) = 1;
271 /* The source location has been lost, and doesn't really matter.
272 We need to set it to something though. */
273 gfc_set_decl_location (decl, &gfc_current_locus);
275 gfc_add_decl_to_function (decl);
277 return decl;
281 /* Get storage for common block. */
283 static tree
284 build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
286 gfc_symbol *common_sym;
287 tree decl;
289 /* Create a namespace to store symbols for common blocks. */
290 if (gfc_common_ns == NULL)
291 gfc_common_ns = gfc_get_namespace (NULL, 0);
293 gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
294 decl = common_sym->backend_decl;
296 /* Update the size of this common block as needed. */
297 if (decl != NULL_TREE)
299 tree size = TYPE_SIZE_UNIT (union_type);
300 if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
302 /* Named common blocks of the same name shall be of the same size
303 in all scoping units of a program in which they appear, but
304 blank common blocks may be of different sizes. */
305 if (strcmp (com->name, BLANK_COMMON_NAME))
306 gfc_warning ("Named COMMON block '%s' at %L shall be of the "
307 "same size", com->name, &com->where);
308 DECL_SIZE_UNIT (decl) = size;
312 /* If this common block has been declared in a previous program unit,
313 and either it is already initialized or there is no new initialization
314 for it, just return. */
315 if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
316 return decl;
318 /* If there is no backend_decl for the common block, build it. */
319 if (decl == NULL_TREE)
321 decl = build_decl (VAR_DECL, get_identifier (com->name), union_type);
322 SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com->name));
323 TREE_PUBLIC (decl) = 1;
324 TREE_STATIC (decl) = 1;
325 DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
326 DECL_USER_ALIGN (decl) = 0;
328 gfc_set_decl_location (decl, &com->where);
330 /* Place the back end declaration for this common block in
331 GLOBAL_BINDING_LEVEL. */
332 common_sym->backend_decl = pushdecl_top_level (decl);
335 /* Has no initial values. */
336 if (!is_init)
338 DECL_INITIAL (decl) = NULL_TREE;
339 DECL_COMMON (decl) = 1;
340 DECL_DEFER_OUTPUT (decl) = 1;
342 else
344 DECL_INITIAL (decl) = error_mark_node;
345 DECL_COMMON (decl) = 0;
346 DECL_DEFER_OUTPUT (decl) = 0;
348 return decl;
352 /* Declare memory for the common block or local equivalence, and create
353 backend declarations for all of the elements. */
355 static void
356 create_common (gfc_common_head *com, segment_info * head)
358 segment_info *s, *next_s;
359 tree union_type;
360 tree *field_link;
361 record_layout_info rli;
362 tree decl;
363 bool is_init = false;
365 /* Declare the variables inside the common block. */
366 union_type = make_node (UNION_TYPE);
367 rli = start_record_layout (union_type);
368 field_link = &TYPE_FIELDS (union_type);
370 for (s = head; s; s = s->next)
372 build_field (s, union_type, rli);
374 /* Link the field into the type. */
375 *field_link = s->field;
376 field_link = &TREE_CHAIN (s->field);
378 /* Has initial value. */
379 if (s->sym->value)
380 is_init = true;
382 finish_record_layout (rli, true);
384 if (com)
385 decl = build_common_decl (com, union_type, is_init);
386 else
387 decl = build_equiv_decl (union_type, is_init);
389 if (is_init)
391 tree list, ctor, tmp;
392 HOST_WIDE_INT offset = 0;
394 list = NULL_TREE;
395 for (s = head; s; s = s->next)
397 if (s->sym->value)
399 if (s->offset < offset)
401 /* We have overlapping initializers. It could either be
402 partially initialized arrays (legal), or the user
403 specified multiple initial values (illegal).
404 We don't implement this yet, so bail out. */
405 gfc_todo_error ("Initialization of overlapping variables");
407 /* Add the initializer for this field. */
408 tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
409 TREE_TYPE (s->field), s->sym->attr.dimension,
410 s->sym->attr.pointer || s->sym->attr.allocatable);
411 list = tree_cons (s->field, tmp, list);
412 offset = s->offset + s->length;
415 gcc_assert (list);
416 ctor = build1 (CONSTRUCTOR, union_type, nreverse(list));
417 TREE_CONSTANT (ctor) = 1;
418 TREE_INVARIANT (ctor) = 1;
419 TREE_STATIC (ctor) = 1;
420 DECL_INITIAL (decl) = ctor;
422 #ifdef ENABLE_CHECKING
423 for (tmp = CONSTRUCTOR_ELTS (ctor); tmp; tmp = TREE_CHAIN (tmp))
424 gcc_assert (TREE_CODE (TREE_PURPOSE (tmp)) == FIELD_DECL);
425 #endif
428 /* Build component reference for each variable. */
429 for (s = head; s; s = next_s)
431 s->sym->backend_decl = build3 (COMPONENT_REF, TREE_TYPE (s->field),
432 decl, s->field, NULL_TREE);
434 next_s = s->next;
435 gfc_free (s);
440 /* Given a symbol, find it in the current segment list. Returns NULL if
441 not found. */
443 static segment_info *
444 find_segment_info (gfc_symbol *symbol)
446 segment_info *n;
448 for (n = current_segment; n; n = n->next)
450 if (n->sym == symbol)
451 return n;
454 return NULL;
458 /* Given an expression node, make sure it is a constant integer and return
459 the mpz_t value. */
461 static mpz_t *
462 get_mpz (gfc_expr *e)
465 if (e->expr_type != EXPR_CONSTANT)
466 gfc_internal_error ("get_mpz(): Not an integer constant");
468 return &e->value.integer;
472 /* Given an array specification and an array reference, figure out the
473 array element number (zero based). Bounds and elements are guaranteed
474 to be constants. If something goes wrong we generate an error and
475 return zero. */
477 static HOST_WIDE_INT
478 element_number (gfc_array_ref *ar)
480 mpz_t multiplier, offset, extent, n;
481 gfc_array_spec *as;
482 HOST_WIDE_INT i, rank;
484 as = ar->as;
485 rank = as->rank;
486 mpz_init_set_ui (multiplier, 1);
487 mpz_init_set_ui (offset, 0);
488 mpz_init (extent);
489 mpz_init (n);
491 for (i = 0; i < rank; i++)
493 if (ar->dimen_type[i] != DIMEN_ELEMENT)
494 gfc_internal_error ("element_number(): Bad dimension type");
496 mpz_sub (n, *get_mpz (ar->start[i]), *get_mpz (as->lower[i]));
498 mpz_mul (n, n, multiplier);
499 mpz_add (offset, offset, n);
501 mpz_sub (extent, *get_mpz (as->upper[i]), *get_mpz (as->lower[i]));
502 mpz_add_ui (extent, extent, 1);
504 if (mpz_sgn (extent) < 0)
505 mpz_set_ui (extent, 0);
507 mpz_mul (multiplier, multiplier, extent);
510 i = mpz_get_ui (offset);
512 mpz_clear (multiplier);
513 mpz_clear (offset);
514 mpz_clear (extent);
515 mpz_clear (n);
517 return i;
521 /* Given a single element of an equivalence list, figure out the offset
522 from the base symbol. For simple variables or full arrays, this is
523 simply zero. For an array element we have to calculate the array
524 element number and multiply by the element size. For a substring we
525 have to calculate the further reference. */
527 static HOST_WIDE_INT
528 calculate_offset (gfc_expr *e)
530 HOST_WIDE_INT n, element_size, offset;
531 gfc_typespec *element_type;
532 gfc_ref *reference;
534 offset = 0;
535 element_type = &e->symtree->n.sym->ts;
537 for (reference = e->ref; reference; reference = reference->next)
538 switch (reference->type)
540 case REF_ARRAY:
541 switch (reference->u.ar.type)
543 case AR_FULL:
544 break;
546 case AR_ELEMENT:
547 n = element_number (&reference->u.ar);
548 if (element_type->type == BT_CHARACTER)
549 gfc_conv_const_charlen (element_type->cl);
550 element_size =
551 int_size_in_bytes (gfc_typenode_for_spec (element_type));
552 offset += n * element_size;
553 break;
555 default:
556 gfc_error ("Bad array reference at %L", &e->where);
558 break;
559 case REF_SUBSTRING:
560 if (reference->u.ss.start != NULL)
561 offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
562 break;
563 default:
564 gfc_error ("Illegal reference type at %L as EQUIVALENCE object",
565 &e->where);
567 return offset;
571 /* Add a new segment_info structure to the current segment. eq1 is already
572 in the list, eq2 is not. */
574 static void
575 new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
577 HOST_WIDE_INT offset1, offset2;
578 segment_info *a;
580 offset1 = calculate_offset (eq1->expr);
581 offset2 = calculate_offset (eq2->expr);
583 a = get_segment_info (eq2->expr->symtree->n.sym,
584 v->offset + offset1 - offset2);
586 current_segment = add_segments (current_segment, a);
590 /* Given two equivalence structures that are both already in the list, make
591 sure that this new condition is not violated, generating an error if it
592 is. */
594 static void
595 confirm_condition (segment_info *s1, gfc_equiv *eq1, segment_info *s2,
596 gfc_equiv *eq2)
598 HOST_WIDE_INT offset1, offset2;
600 offset1 = calculate_offset (eq1->expr);
601 offset2 = calculate_offset (eq2->expr);
603 if (s1->offset + offset1 != s2->offset + offset2)
604 gfc_error ("Inconsistent equivalence rules involving '%s' at %L and "
605 "'%s' at %L", s1->sym->name, &s1->sym->declared_at,
606 s2->sym->name, &s2->sym->declared_at);
610 /* Process a new equivalence condition. eq1 is know to be in segment f.
611 If eq2 is also present then confirm that the condition holds.
612 Otherwise add a new variable to the segment list. */
614 static void
615 add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
617 segment_info *n;
619 n = find_segment_info (eq2->expr->symtree->n.sym);
621 if (n == NULL)
622 new_condition (f, eq1, eq2);
623 else
624 confirm_condition (f, eq1, n, eq2);
628 /* Given a segment element, search through the equivalence lists for unused
629 conditions that involve the symbol. Add these rules to the segment. Only
630 checks for rules involving the first symbol in the equivalence set. */
632 static bool
633 find_equivalence (segment_info *n)
635 gfc_equiv *e1, *e2, *eq, *other;
636 bool found;
638 found = FALSE;
639 for (e1 = n->sym->ns->equiv; e1; e1 = e1->next)
641 other = NULL;
642 for (e2 = e1->eq; e2; e2 = e2->eq)
644 if (e2->used)
645 continue;
647 if (e1->expr->symtree->n.sym == n->sym)
649 eq = e1;
650 other = e2;
652 else if (e2->expr->symtree->n.sym == n->sym)
654 eq = e2;
655 other = e1;
657 else
658 eq = NULL;
660 if (eq)
662 add_condition (n, eq, other);
663 eq->used = 1;
664 found = TRUE;
665 /* If this symbol is the first in the chain we may find other
666 matches. Otherwise we can skip to the next equivalence. */
667 if (eq == e2)
668 break;
672 return found;
676 /* Add all symbols equivalenced within a segment. We need to scan the
677 segment list multiple times to include indirect equivalences. */
679 static void
680 add_equivalences (void)
682 segment_info *f;
683 bool more;
685 more = TRUE;
686 while (more)
688 more = FALSE;
689 for (f = current_segment; f; f = f->next)
691 if (!f->sym->equiv_built)
693 f->sym->equiv_built = 1;
694 more = find_equivalence (f);
701 /* Returns the offset necessary to properly align the current equivalence.
702 Sets *palign to the required alignment. */
704 static HOST_WIDE_INT
705 align_segment (unsigned HOST_WIDE_INT * palign)
707 segment_info *s;
708 unsigned HOST_WIDE_INT offset;
709 unsigned HOST_WIDE_INT max_align;
710 unsigned HOST_WIDE_INT this_align;
711 unsigned HOST_WIDE_INT this_offset;
713 max_align = 1;
714 offset = 0;
715 for (s = current_segment; s; s = s->next)
717 this_align = TYPE_ALIGN_UNIT (s->field);
718 if (s->offset & (this_align - 1))
720 /* Field is misaligned. */
721 this_offset = this_align - ((s->offset + offset) & (this_align - 1));
722 if (this_offset & (max_align - 1))
724 /* Aligning this field would misalign a previous field. */
725 gfc_error ("The equivalence set for variable '%s' "
726 "declared at %L violates alignment requirents",
727 s->sym->name, &s->sym->declared_at);
729 offset += this_offset;
731 max_align = this_align;
733 if (palign)
734 *palign = max_align;
735 return offset;
739 /* Adjust segment offsets by the given amount. */
741 static void
742 apply_segment_offset (segment_info * s, HOST_WIDE_INT offset)
744 for (; s; s = s->next)
745 s->offset += offset;
749 /* Lay out a symbol in a common block. If the symbol has already been seen
750 then check the location is consistent. Otherwise create segments
751 for that symbol and all the symbols equivalenced with it. */
753 /* Translate a single common block. */
755 static void
756 translate_common (gfc_common_head *common, gfc_symbol *var_list)
758 gfc_symbol *sym;
759 segment_info *s;
760 segment_info *common_segment;
761 HOST_WIDE_INT offset;
762 HOST_WIDE_INT current_offset;
763 unsigned HOST_WIDE_INT align;
764 unsigned HOST_WIDE_INT max_align;
766 common_segment = NULL;
767 current_offset = 0;
768 max_align = 1;
770 /* Add symbols to the segment. */
771 for (sym = var_list; sym; sym = sym->common_next)
773 if (sym->equiv_built)
775 /* Symbol has already been added via an equivalence. */
776 current_segment = common_segment;
777 s = find_segment_info (sym);
779 /* Ensure the current location is properly aligned. */
780 align = TYPE_ALIGN_UNIT (s->field);
781 current_offset = (current_offset + align - 1) &~ (align - 1);
783 /* Verify that it ended up where we expect it. */
784 if (s->offset != current_offset)
786 gfc_error ("Equivalence for '%s' does not match ordering of "
787 "COMMON '%s' at %L", sym->name,
788 common->name, &common->where);
791 else
793 /* A symbol we haven't seen before. */
794 s = current_segment = get_segment_info (sym, current_offset);
796 /* Add all objects directly or indirectly equivalenced with this
797 symbol. */
798 add_equivalences ();
800 if (current_segment->offset < 0)
801 gfc_error ("The equivalence set for '%s' cause an invalid "
802 "extension to COMMON '%s' at %L", sym->name,
803 common->name, &common->where);
805 offset = align_segment (&align);
807 if (offset & (max_align - 1))
809 /* The required offset conflicts with previous alignment
810 requirements. Insert padding immediately before this
811 segment. */
812 gfc_warning ("Padding of %d bytes required before '%s' in "
813 "COMMON '%s' at %L", offset, s->sym->name,
814 common->name, &common->where);
816 else
818 /* Offset the whole common block. */
819 apply_segment_offset (common_segment, offset);
822 /* Apply the offset to the new segments. */
823 apply_segment_offset (current_segment, offset);
824 current_offset += offset;
825 if (max_align < align)
826 max_align = align;
828 /* Add the new segments to the common block. */
829 common_segment = add_segments (common_segment, current_segment);
832 /* The offset of the next common variable. */
833 current_offset += s->length;
836 if (common_segment->offset != 0)
838 gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start",
839 common->name, &common->where, common_segment->offset);
842 create_common (common, common_segment);
846 /* Create a new block for each merged equivalence list. */
848 static void
849 finish_equivalences (gfc_namespace *ns)
851 gfc_equiv *z, *y;
852 gfc_symbol *sym;
853 HOST_WIDE_INT offset;
854 unsigned HOST_WIDE_INT align;
856 for (z = ns->equiv; z; z = z->next)
857 for (y = z->eq; y; y = y->eq)
859 if (y->used)
860 continue;
861 sym = z->expr->symtree->n.sym;
862 current_segment = get_segment_info (sym, 0);
864 /* All objects directly or indirectly equivalenced with this symbol. */
865 add_equivalences ();
867 /* Align the block. */
868 offset = align_segment (&align);
870 /* Ensure all offsets are positive. */
871 offset -= current_segment->offset & ~(align - 1);
873 apply_segment_offset (current_segment, offset);
875 /* Create the decl. */
876 create_common (NULL, current_segment);
877 break;
882 /* Work function for translating a named common block. */
884 static void
885 named_common (gfc_symtree *st)
887 translate_common (st->n.common, st->n.common->head);
891 /* Translate the common blocks in a namespace. Unlike other variables,
892 these have to be created before code, because the backend_decl depends
893 on the rest of the common block. */
895 void
896 gfc_trans_common (gfc_namespace *ns)
898 gfc_common_head *c;
900 /* Translate the blank common block. */
901 if (ns->blank_common.head != NULL)
903 c = gfc_get_common_head ();
904 /* We've lost the real location, so use the location of the
905 enclosing procedure. */
906 c->where = ns->proc_name->declared_at;
907 strcpy (c->name, BLANK_COMMON_NAME);
908 translate_common (c, ns->blank_common.head);
911 /* Translate all named common blocks. */
912 gfc_traverse_symtree (ns->common_root, named_common);
914 /* Commit the newly created symbols for common blocks. */
915 gfc_commit_symbols ();
917 /* Translate local equivalence. */
918 finish_equivalences (ns);