]> gcc.gnu.org Git - gcc.git/blame - gcc/fortran/trans-common.c
decl.c: Miscellaneous whitespace fixes.
[gcc.git] / gcc / fortran / trans-common.c
CommitLineData
6de9cd9a 1/* Common block and equivalence list handling
710a179f 2 Copyright (C) 2000, 2003, 2004, 2005, 2006, 2007
6c7a4dfd 3 Free Software Foundation, Inc.
6de9cd9a
DN
4 Contributed by Canqun Yang <canqun@nudt.edu.cn>
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
6de9cd9a 12
9fc4d79b
TS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
9fc4d79b 19along with GCC; see the file COPYING. If not, write to the Free
ab57747b
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA. */
6de9cd9a
DN
22
23/* The core algorithm is based on Andy Vaught's g95 tree. Also the
24 way to build UNION_TYPE is borrowed from Richard Henderson.
25
26 Transform common blocks. An integral part of this is processing
1f2959f0 27 equivalence variables. Equivalenced variables that are not in a
6de9cd9a
DN
28 common block end up in a private block of their own.
29
30 Each common block or local equivalence list is declared as a union.
31 Variables within the block are represented as a field within the
32 block with the proper offset.
33
34 So if two variables are equivalenced, they just point to a common
35 area in memory.
36
37 Mathematically, laying out an equivalence block is equivalent to
38 solving a linear system of equations. The matrix is usually a
39 sparse matrix in which each row contains all zero elements except
40 for a +1 and a -1, a sort of a generalized Vandermonde matrix. The
41 matrix is usually block diagonal. The system can be
42 overdetermined, underdetermined or have a unique solution. If the
43 system is inconsistent, the program is not standard conforming.
44 The solution vector is integral, since all of the pivots are +1 or -1.
45
46 How we lay out an equivalence block is a little less complicated.
47 In an equivalence list with n elements, there are n-1 conditions to
48 be satisfied. The conditions partition the variables into what we
49 will call segments. If A and B are equivalenced then A and B are
50 in the same segment. If B and C are equivalenced as well, then A,
51 B and C are in a segment and so on. Each segment is a block of
52 memory that has one or more variables equivalenced in some way. A
53 common block is made up of a series of segments that are joined one
54 after the other. In the linear system, a segment is a block
55 diagonal.
56
57 To lay out a segment we first start with some variable and
58 determine its length. The first variable is assumed to start at
59 offset one and extends to however long it is. We then traverse the
60 list of equivalences to find an unused condition that involves at
61 least one of the variables currently in the segment.
62
63 Each equivalence condition amounts to the condition B+b=C+c where B
64 and C are the offsets of the B and C variables, and b and c are
65 constants which are nonzero for array elements, substrings or
66 structure components. So for
67
68 EQUIVALENCE(B(2), C(3))
69 we have
70 B + 2*size of B's elements = C + 3*size of C's elements.
71
72 If B and C are known we check to see if the condition already
73 holds. If B is known we can solve for C. Since we know the length
74 of C, we can see if the minimum and maximum extents of the segment
75 are affected. Eventually, we make a full pass through the
76 equivalence list without finding any new conditions and the segment
77 is fully specified.
78
79 At this point, the segment is added to the current common block.
80 Since we know the minimum extent of the segment, everything in the
81 segment is translated to its position in the common block. The
82 usual case here is that there are no equivalence statements and the
83 common block is series of segments with one variable each, which is
84 a diagonal matrix in the matrix formulation.
85
5291e69a 86 Each segment is described by a chain of segment_info structures. Each
e2ae1407 87 segment_info structure describes the extents of a single variable within
5291e69a
PB
88 the segment. This list is maintained in the order the elements are
89 positioned withing the segment. If two elements have the same starting
90 offset the smaller will come first. If they also have the same size their
91 ordering is undefined.
92
6de9cd9a
DN
93 Once all common blocks have been created, the list of equivalences
94 is examined for still-unused equivalence conditions. We create a
95 block for each merged equivalence list. */
96
97#include "config.h"
98#include "system.h"
99#include "coretypes.h"
6c7a4dfd 100#include "target.h"
6de9cd9a
DN
101#include "tree.h"
102#include "toplev.h"
103#include "tm.h"
25f2dfd3 104#include "rtl.h"
6de9cd9a
DN
105#include "gfortran.h"
106#include "trans.h"
107#include "trans-types.h"
108#include "trans-const.h"
109
110
49de9e73 111/* Holds a single variable in an equivalence set. */
6de9cd9a
DN
112typedef struct segment_info
113{
114 gfc_symbol *sym;
5291e69a
PB
115 HOST_WIDE_INT offset;
116 HOST_WIDE_INT length;
ad6e2a18 117 /* This will contain the field type until the field is created. */
a8a6b603 118 tree field;
6de9cd9a
DN
119 struct segment_info *next;
120} segment_info;
121
832ef1ce 122static segment_info * current_segment;
6de9cd9a
DN
123static gfc_namespace *gfc_common_ns = NULL;
124
61321991 125
ad6e2a18
TS
126/* Make a segment_info based on a symbol. */
127
128static segment_info *
129get_segment_info (gfc_symbol * sym, HOST_WIDE_INT offset)
130{
131 segment_info *s;
132
133 /* Make sure we've got the character length. */
134 if (sym->ts.type == BT_CHARACTER)
135 gfc_conv_const_charlen (sym->ts.cl);
136
137 /* Create the segment_info and fill it in. */
138 s = (segment_info *) gfc_getmem (sizeof (segment_info));
139 s->sym = sym;
13795658 140 /* We will use this type when building the segment aggregate type. */
ad6e2a18
TS
141 s->field = gfc_sym_type (sym);
142 s->length = int_size_in_bytes (s->field);
143 s->offset = offset;
144
145 return s;
146}
147
61321991
PT
148
149/* Add a copy of a segment list to the namespace. This is specifically for
150 equivalence segments, so that dependency checking can be done on
151 equivalence group members. */
152
153static void
154copy_equiv_list_to_ns (segment_info *c)
155{
156 segment_info *f;
157 gfc_equiv_info *s;
158 gfc_equiv_list *l;
159
160 l = (gfc_equiv_list *) gfc_getmem (sizeof (gfc_equiv_list));
161
162 l->next = c->sym->ns->equiv_lists;
163 c->sym->ns->equiv_lists = l;
164
165 for (f = c; f; f = f->next)
166 {
167 s = (gfc_equiv_info *) gfc_getmem (sizeof (gfc_equiv_info));
168 s->next = l->equiv;
169 l->equiv = s;
170 s->sym = f->sym;
171 s->offset = f->offset;
37311e71 172 s->length = f->length;
61321991
PT
173 }
174}
175
176
a8a6b603 177/* Add combine segment V and segment LIST. */
5291e69a
PB
178
179static segment_info *
180add_segments (segment_info *list, segment_info *v)
181{
182 segment_info *s;
183 segment_info *p;
184 segment_info *next;
a8a6b603 185
5291e69a
PB
186 p = NULL;
187 s = list;
188
189 while (v)
190 {
191 /* Find the location of the new element. */
192 while (s)
193 {
194 if (v->offset < s->offset)
195 break;
196 if (v->offset == s->offset
197 && v->length <= s->length)
198 break;
199
200 p = s;
201 s = s->next;
202 }
203
204 /* Insert the new element in between p and s. */
205 next = v->next;
206 v->next = s;
207 if (p == NULL)
208 list = v;
209 else
210 p->next = v;
211
212 p = v;
213 v = next;
214 }
a8a6b603 215
5291e69a
PB
216 return list;
217}
218
6de9cd9a
DN
219/* Construct mangled common block name from symbol name. */
220
221static tree
41433497 222gfc_sym_mangled_common_id (const char *name)
6de9cd9a
DN
223{
224 int has_underscore;
9056bd70 225 char mangled_name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
6de9cd9a 226
9056bd70
TS
227 if (strcmp (name, BLANK_COMMON_NAME) == 0)
228 return get_identifier (name);
a8a6b603 229
6de9cd9a
DN
230 if (gfc_option.flag_underscoring)
231 {
9056bd70 232 has_underscore = strchr (name, '_') != 0;
6de9cd9a 233 if (gfc_option.flag_second_underscore && has_underscore)
9056bd70 234 snprintf (mangled_name, sizeof mangled_name, "%s__", name);
6de9cd9a 235 else
9056bd70 236 snprintf (mangled_name, sizeof mangled_name, "%s_", name);
a8a6b603 237
9056bd70 238 return get_identifier (mangled_name);
6de9cd9a
DN
239 }
240 else
9056bd70 241 return get_identifier (name);
6de9cd9a
DN
242}
243
244
ad6e2a18 245/* Build a field declaration for a common variable or a local equivalence
6de9cd9a
DN
246 object. */
247
ad6e2a18 248static void
6de9cd9a
DN
249build_field (segment_info *h, tree union_type, record_layout_info rli)
250{
ad6e2a18
TS
251 tree field;
252 tree name;
6de9cd9a 253 HOST_WIDE_INT offset = h->offset;
5291e69a 254 unsigned HOST_WIDE_INT desired_align, known_align;
6de9cd9a 255
ad6e2a18
TS
256 name = get_identifier (h->sym->name);
257 field = build_decl (FIELD_DECL, name, h->field);
c8cc8542 258 gfc_set_decl_location (field, &h->sym->declared_at);
6de9cd9a
DN
259 known_align = (offset & -offset) * BITS_PER_UNIT;
260 if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
261 known_align = BIGGEST_ALIGNMENT;
262
263 desired_align = update_alignment_for_field (rli, field, known_align);
264 if (desired_align > known_align)
265 DECL_PACKED (field) = 1;
266
267 DECL_FIELD_CONTEXT (field) = union_type;
268 DECL_FIELD_OFFSET (field) = size_int (offset);
269 DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
270 SET_DECL_OFFSET_ALIGN (field, known_align);
271
272 rli->offset = size_binop (MAX_EXPR, rli->offset,
273 size_binop (PLUS_EXPR,
274 DECL_FIELD_OFFSET (field),
275 DECL_SIZE_UNIT (field)));
ce2df7c6 276 /* If this field is assigned to a label, we create another two variables.
81871c2a 277 One will hold the address of target label or format label. The other will
ce2df7c6
FW
278 hold the length of format label string. */
279 if (h->sym->attr.assign)
280 {
281 tree len;
282 tree addr;
283
284 gfc_allocate_lang_decl (field);
285 GFC_DECL_ASSIGN (field) = 1;
286 len = gfc_create_var_np (gfc_charlen_type_node,h->sym->name);
287 addr = gfc_create_var_np (pvoid_type_node, h->sym->name);
288 TREE_STATIC (len) = 1;
289 TREE_STATIC (addr) = 1;
290 DECL_INITIAL (len) = build_int_cst (NULL_TREE, -2);
291 gfc_set_decl_location (len, &h->sym->declared_at);
292 gfc_set_decl_location (addr, &h->sym->declared_at);
293 GFC_DECL_STRING_LEN (field) = pushdecl_top_level (len);
294 GFC_DECL_ASSIGN_ADDR (field) = pushdecl_top_level (addr);
295 }
296
ad6e2a18 297 h->field = field;
6de9cd9a
DN
298}
299
300
301/* Get storage for local equivalence. */
302
303static tree
57f0d086 304build_equiv_decl (tree union_type, bool is_init, bool is_saved)
6de9cd9a
DN
305{
306 tree decl;
bae88af6
TS
307 char name[15];
308 static int serial = 0;
5291e69a
PB
309
310 if (is_init)
311 {
312 decl = gfc_create_var (union_type, "equiv");
313 TREE_STATIC (decl) = 1;
6c7a4dfd 314 GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
5291e69a
PB
315 return decl;
316 }
317
bae88af6
TS
318 snprintf (name, sizeof (name), "equiv.%d", serial++);
319 decl = build_decl (VAR_DECL, get_identifier (name), union_type);
6de9cd9a 320 DECL_ARTIFICIAL (decl) = 1;
bae88af6 321 DECL_IGNORED_P (decl) = 1;
6de9cd9a 322
57f0d086
JJ
323 if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
324 || is_saved)
bae88af6 325 TREE_STATIC (decl) = 1;
6de9cd9a
DN
326
327 TREE_ADDRESSABLE (decl) = 1;
328 TREE_USED (decl) = 1;
6c7a4dfd 329 GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
c8cc8542
PB
330
331 /* The source location has been lost, and doesn't really matter.
332 We need to set it to something though. */
333 gfc_set_decl_location (decl, &gfc_current_locus);
334
6de9cd9a
DN
335 gfc_add_decl_to_function (decl);
336
337 return decl;
338}
339
340
341/* Get storage for common block. */
342
343static tree
53814b8f 344build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
6de9cd9a
DN
345{
346 gfc_symbol *common_sym;
347 tree decl;
348
349 /* Create a namespace to store symbols for common blocks. */
350 if (gfc_common_ns == NULL)
0366dfe9 351 gfc_common_ns = gfc_get_namespace (NULL, 0);
6de9cd9a 352
53814b8f 353 gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
6de9cd9a
DN
354 decl = common_sym->backend_decl;
355
356 /* Update the size of this common block as needed. */
357 if (decl != NULL_TREE)
358 {
5291e69a 359 tree size = TYPE_SIZE_UNIT (union_type);
6de9cd9a
DN
360 if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
361 {
362 /* Named common blocks of the same name shall be of the same size
363 in all scoping units of a program in which they appear, but
364 blank common blocks may be of different sizes. */
53814b8f 365 if (strcmp (com->name, BLANK_COMMON_NAME))
a8a6b603 366 gfc_warning ("Named COMMON block '%s' at %L shall be of the "
53814b8f 367 "same size", com->name, &com->where);
6de9cd9a
DN
368 DECL_SIZE_UNIT (decl) = size;
369 }
370 }
371
372 /* If this common block has been declared in a previous program unit,
373 and either it is already initialized or there is no new initialization
374 for it, just return. */
375 if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
376 return decl;
377
378 /* If there is no backend_decl for the common block, build it. */
379 if (decl == NULL_TREE)
380 {
53814b8f
TS
381 decl = build_decl (VAR_DECL, get_identifier (com->name), union_type);
382 SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com->name));
6de9cd9a
DN
383 TREE_PUBLIC (decl) = 1;
384 TREE_STATIC (decl) = 1;
385 DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
386 DECL_USER_ALIGN (decl) = 0;
6c7a4dfd 387 GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
5291e69a 388
c8cc8542
PB
389 gfc_set_decl_location (decl, &com->where);
390
8893239d 391 if (com->threadprivate)
6c7a4dfd
JJ
392 DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
393
5291e69a
PB
394 /* Place the back end declaration for this common block in
395 GLOBAL_BINDING_LEVEL. */
396 common_sym->backend_decl = pushdecl_top_level (decl);
6de9cd9a
DN
397 }
398
399 /* Has no initial values. */
400 if (!is_init)
401 {
402 DECL_INITIAL (decl) = NULL_TREE;
403 DECL_COMMON (decl) = 1;
404 DECL_DEFER_OUTPUT (decl) = 1;
6de9cd9a
DN
405 }
406 else
407 {
408 DECL_INITIAL (decl) = error_mark_node;
409 DECL_COMMON (decl) = 0;
410 DECL_DEFER_OUTPUT (decl) = 0;
6de9cd9a
DN
411 }
412 return decl;
413}
414
415
416/* Declare memory for the common block or local equivalence, and create
417 backend declarations for all of the elements. */
418
419static void
66e4ab31 420create_common (gfc_common_head *com, segment_info *head, bool saw_equiv)
a8a6b603
TS
421{
422 segment_info *s, *next_s;
6de9cd9a
DN
423 tree union_type;
424 tree *field_link;
425 record_layout_info rli;
426 tree decl;
427 bool is_init = false;
57f0d086 428 bool is_saved = false;
6de9cd9a 429
a3122424
CY
430 /* Declare the variables inside the common block.
431 If the current common block contains any equivalence object, then
432 make a UNION_TYPE node, otherwise RECORD_TYPE. This will let the
433 alias analyzer work well when there is no address overlapping for
434 common variables in the current common block. */
435 if (saw_equiv)
436 union_type = make_node (UNION_TYPE);
437 else
438 union_type = make_node (RECORD_TYPE);
439
6de9cd9a
DN
440 rli = start_record_layout (union_type);
441 field_link = &TYPE_FIELDS (union_type);
442
832ef1ce 443 for (s = head; s; s = s->next)
6de9cd9a 444 {
a8a6b603 445 build_field (s, union_type, rli);
6de9cd9a
DN
446
447 /* Link the field into the type. */
a8a6b603
TS
448 *field_link = s->field;
449 field_link = &TREE_CHAIN (s->field);
ad6e2a18 450
a8a6b603
TS
451 /* Has initial value. */
452 if (s->sym->value)
6de9cd9a 453 is_init = true;
57f0d086
JJ
454
455 /* Has SAVE attribute. */
456 if (s->sym->attr.save)
457 is_saved = true;
6de9cd9a
DN
458 }
459 finish_record_layout (rli, true);
460
9056bd70 461 if (com)
53814b8f 462 decl = build_common_decl (com, union_type, is_init);
6de9cd9a 463 else
57f0d086 464 decl = build_equiv_decl (union_type, is_init, is_saved);
6de9cd9a 465
5291e69a
PB
466 if (is_init)
467 {
4038c495 468 tree ctor, tmp;
5291e69a 469 HOST_WIDE_INT offset = 0;
4038c495 470 VEC(constructor_elt,gc) *v = NULL;
5291e69a 471
832ef1ce 472 for (s = head; s; s = s->next)
5291e69a 473 {
a8a6b603 474 if (s->sym->value)
5291e69a 475 {
a8a6b603 476 if (s->offset < offset)
5291e69a
PB
477 {
478 /* We have overlapping initializers. It could either be
1f2959f0 479 partially initialized arrays (legal), or the user
5291e69a
PB
480 specified multiple initial values (illegal).
481 We don't implement this yet, so bail out. */
482 gfc_todo_error ("Initialization of overlapping variables");
483 }
597073ac
PB
484 /* Add the initializer for this field. */
485 tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
66e4ab31
SK
486 TREE_TYPE (s->field),
487 s->sym->attr.dimension,
488 s->sym->attr.pointer
489 || s->sym->attr.allocatable);
4038c495
GB
490
491 CONSTRUCTOR_APPEND_ELT (v, s->field, tmp);
a8a6b603 492 offset = s->offset + s->length;
5291e69a
PB
493 }
494 }
4038c495
GB
495 gcc_assert (!VEC_empty (constructor_elt, v));
496 ctor = build_constructor (union_type, v);
5291e69a
PB
497 TREE_CONSTANT (ctor) = 1;
498 TREE_INVARIANT (ctor) = 1;
499 TREE_STATIC (ctor) = 1;
500 DECL_INITIAL (decl) = ctor;
501
502#ifdef ENABLE_CHECKING
4038c495
GB
503 {
504 tree field, value;
505 unsigned HOST_WIDE_INT idx;
506 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, field, value)
507 gcc_assert (TREE_CODE (field) == FIELD_DECL);
508 }
5291e69a
PB
509#endif
510 }
511
6de9cd9a 512 /* Build component reference for each variable. */
832ef1ce 513 for (s = head; s; s = next_s)
6de9cd9a 514 {
81871c2a
JJ
515 tree var_decl;
516
517 var_decl = build_decl (VAR_DECL, DECL_NAME (s->field),
518 TREE_TYPE (s->field));
519 gfc_set_decl_location (var_decl, &s->sym->declared_at);
520 TREE_PUBLIC (var_decl) = TREE_PUBLIC (decl);
521 TREE_STATIC (var_decl) = TREE_STATIC (decl);
522 TREE_USED (var_decl) = TREE_USED (decl);
523 if (s->sym->attr.target)
524 TREE_ADDRESSABLE (var_decl) = 1;
525 /* This is a fake variable just for debugging purposes. */
526 TREE_ASM_WRITTEN (var_decl) = 1;
527
528 if (com)
529 var_decl = pushdecl_top_level (var_decl);
530 else
531 gfc_add_decl_to_function (var_decl);
532
533 SET_DECL_VALUE_EXPR (var_decl,
534 build3 (COMPONENT_REF, TREE_TYPE (s->field),
535 decl, s->field, NULL_TREE));
536 DECL_HAS_VALUE_EXPR_P (var_decl) = 1;
6c7a4dfd 537 GFC_DECL_COMMON_OR_EQUIV (var_decl) = 1;
81871c2a
JJ
538
539 if (s->sym->attr.assign)
540 {
541 gfc_allocate_lang_decl (var_decl);
542 GFC_DECL_ASSIGN (var_decl) = 1;
543 GFC_DECL_STRING_LEN (var_decl) = GFC_DECL_STRING_LEN (s->field);
544 GFC_DECL_ASSIGN_ADDR (var_decl) = GFC_DECL_ASSIGN_ADDR (s->field);
545 }
546
547 s->sym->backend_decl = var_decl;
6de9cd9a 548
a8a6b603
TS
549 next_s = s->next;
550 gfc_free (s);
6de9cd9a 551 }
a8a6b603 552}
6de9cd9a
DN
553
554
555/* Given a symbol, find it in the current segment list. Returns NULL if
a8a6b603 556 not found. */
6de9cd9a 557
a8a6b603 558static segment_info *
6de9cd9a 559find_segment_info (gfc_symbol *symbol)
a8a6b603 560{
6de9cd9a
DN
561 segment_info *n;
562
563 for (n = current_segment; n; n = n->next)
5291e69a
PB
564 {
565 if (n->sym == symbol)
566 return n;
567 }
6de9cd9a 568
a8a6b603
TS
569 return NULL;
570}
6de9cd9a
DN
571
572
6de9cd9a 573/* Given an expression node, make sure it is a constant integer and return
a8a6b603 574 the mpz_t value. */
6de9cd9a 575
a8a6b603
TS
576static mpz_t *
577get_mpz (gfc_expr *e)
6de9cd9a 578{
a8a6b603
TS
579
580 if (e->expr_type != EXPR_CONSTANT)
6de9cd9a
DN
581 gfc_internal_error ("get_mpz(): Not an integer constant");
582
a8a6b603
TS
583 return &e->value.integer;
584}
6de9cd9a
DN
585
586
587/* Given an array specification and an array reference, figure out the
588 array element number (zero based). Bounds and elements are guaranteed
589 to be constants. If something goes wrong we generate an error and
a8a6b603 590 return zero. */
6de9cd9a 591
5291e69a 592static HOST_WIDE_INT
6de9cd9a 593element_number (gfc_array_ref *ar)
a8a6b603
TS
594{
595 mpz_t multiplier, offset, extent, n;
6de9cd9a 596 gfc_array_spec *as;
a8a6b603 597 HOST_WIDE_INT i, rank;
6de9cd9a
DN
598
599 as = ar->as;
600 rank = as->rank;
601 mpz_init_set_ui (multiplier, 1);
602 mpz_init_set_ui (offset, 0);
603 mpz_init (extent);
a8a6b603 604 mpz_init (n);
6de9cd9a 605
a8a6b603 606 for (i = 0; i < rank; i++)
6de9cd9a 607 {
a8a6b603 608 if (ar->dimen_type[i] != DIMEN_ELEMENT)
6de9cd9a
DN
609 gfc_internal_error ("element_number(): Bad dimension type");
610
a8a6b603 611 mpz_sub (n, *get_mpz (ar->start[i]), *get_mpz (as->lower[i]));
6de9cd9a 612
a8a6b603
TS
613 mpz_mul (n, n, multiplier);
614 mpz_add (offset, offset, n);
6de9cd9a 615
a8a6b603 616 mpz_sub (extent, *get_mpz (as->upper[i]), *get_mpz (as->lower[i]));
6de9cd9a
DN
617 mpz_add_ui (extent, extent, 1);
618
619 if (mpz_sgn (extent) < 0)
620 mpz_set_ui (extent, 0);
621
622 mpz_mul (multiplier, multiplier, extent);
623 }
624
a8a6b603 625 i = mpz_get_ui (offset);
6de9cd9a
DN
626
627 mpz_clear (multiplier);
628 mpz_clear (offset);
629 mpz_clear (extent);
a8a6b603 630 mpz_clear (n);
6de9cd9a 631
a8a6b603 632 return i;
6de9cd9a
DN
633}
634
635
636/* Given a single element of an equivalence list, figure out the offset
637 from the base symbol. For simple variables or full arrays, this is
638 simply zero. For an array element we have to calculate the array
639 element number and multiply by the element size. For a substring we
640 have to calculate the further reference. */
641
5291e69a 642static HOST_WIDE_INT
a8a6b603 643calculate_offset (gfc_expr *e)
6de9cd9a 644{
a8a6b603 645 HOST_WIDE_INT n, element_size, offset;
6de9cd9a
DN
646 gfc_typespec *element_type;
647 gfc_ref *reference;
648
649 offset = 0;
a8a6b603 650 element_type = &e->symtree->n.sym->ts;
6de9cd9a 651
a8a6b603 652 for (reference = e->ref; reference; reference = reference->next)
6de9cd9a
DN
653 switch (reference->type)
654 {
655 case REF_ARRAY:
656 switch (reference->u.ar.type)
657 {
658 case AR_FULL:
659 break;
660
661 case AR_ELEMENT:
a8a6b603 662 n = element_number (&reference->u.ar);
6de9cd9a
DN
663 if (element_type->type == BT_CHARACTER)
664 gfc_conv_const_charlen (element_type->cl);
665 element_size =
666 int_size_in_bytes (gfc_typenode_for_spec (element_type));
a8a6b603 667 offset += n * element_size;
6de9cd9a
DN
668 break;
669
670 default:
a8a6b603 671 gfc_error ("Bad array reference at %L", &e->where);
6de9cd9a
DN
672 }
673 break;
674 case REF_SUBSTRING:
675 if (reference->u.ss.start != NULL)
676 offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
677 break;
678 default:
5291e69a 679 gfc_error ("Illegal reference type at %L as EQUIVALENCE object",
a8a6b603
TS
680 &e->where);
681 }
6de9cd9a
DN
682 return offset;
683}
684
a8a6b603 685
5291e69a
PB
686/* Add a new segment_info structure to the current segment. eq1 is already
687 in the list, eq2 is not. */
6de9cd9a
DN
688
689static void
690new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
691{
5291e69a 692 HOST_WIDE_INT offset1, offset2;
6de9cd9a 693 segment_info *a;
a8a6b603 694
6de9cd9a
DN
695 offset1 = calculate_offset (eq1->expr);
696 offset2 = calculate_offset (eq2->expr);
697
ad6e2a18
TS
698 a = get_segment_info (eq2->expr->symtree->n.sym,
699 v->offset + offset1 - offset2);
6de9cd9a 700
5291e69a 701 current_segment = add_segments (current_segment, a);
6de9cd9a
DN
702}
703
704
705/* Given two equivalence structures that are both already in the list, make
706 sure that this new condition is not violated, generating an error if it
707 is. */
708
709static void
a8a6b603 710confirm_condition (segment_info *s1, gfc_equiv *eq1, segment_info *s2,
6de9cd9a
DN
711 gfc_equiv *eq2)
712{
5291e69a 713 HOST_WIDE_INT offset1, offset2;
6de9cd9a
DN
714
715 offset1 = calculate_offset (eq1->expr);
716 offset2 = calculate_offset (eq2->expr);
a8a6b603
TS
717
718 if (s1->offset + offset1 != s2->offset + offset2)
5291e69a 719 gfc_error ("Inconsistent equivalence rules involving '%s' at %L and "
a8a6b603
TS
720 "'%s' at %L", s1->sym->name, &s1->sym->declared_at,
721 s2->sym->name, &s2->sym->declared_at);
722}
723
6de9cd9a 724
5291e69a
PB
725/* Process a new equivalence condition. eq1 is know to be in segment f.
726 If eq2 is also present then confirm that the condition holds.
727 Otherwise add a new variable to the segment list. */
6de9cd9a
DN
728
729static void
5291e69a 730add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
6de9cd9a 731{
5291e69a 732 segment_info *n;
6de9cd9a 733
5291e69a 734 n = find_segment_info (eq2->expr->symtree->n.sym);
6de9cd9a 735
5291e69a
PB
736 if (n == NULL)
737 new_condition (f, eq1, eq2);
738 else
739 confirm_condition (f, eq1, n, eq2);
6de9cd9a
DN
740}
741
742
5291e69a 743/* Given a segment element, search through the equivalence lists for unused
30aabb86
PT
744 conditions that involve the symbol. Add these rules to the segment. */
745
5291e69a 746static bool
a8a6b603 747find_equivalence (segment_info *n)
6de9cd9a 748{
30aabb86 749 gfc_equiv *e1, *e2, *eq;
5291e69a 750 bool found;
30aabb86 751
5291e69a 752 found = FALSE;
30aabb86 753
a8a6b603 754 for (e1 = n->sym->ns->equiv; e1; e1 = e1->next)
5291e69a 755 {
30aabb86 756 eq = NULL;
5291e69a 757
30aabb86
PT
758 /* Search the equivalence list, including the root (first) element
759 for the symbol that owns the segment. */
760 for (e2 = e1; e2; e2 = e2->eq)
761 {
762 if (!e2->used && e2->expr->symtree->n.sym == n->sym)
5291e69a 763 {
a8a6b603 764 eq = e2;
30aabb86 765 break;
5291e69a 766 }
30aabb86
PT
767 }
768
769 /* Go to the next root element. */
770 if (eq == NULL)
771 continue;
772
773 eq->used = 1;
774
775 /* Now traverse the equivalence list matching the offsets. */
776 for (e2 = e1; e2; e2 = e2->eq)
777 {
778 if (!e2->used && e2 != eq)
5291e69a 779 {
30aabb86
PT
780 add_condition (n, eq, e2);
781 e2->used = 1;
5291e69a 782 found = TRUE;
5291e69a
PB
783 }
784 }
785 }
786 return found;
6de9cd9a
DN
787}
788
a8a6b603 789
66e4ab31 790/* Add all symbols equivalenced within a segment. We need to scan the
8a0b57b3
PT
791 segment list multiple times to include indirect equivalences. Since
792 a new segment_info can inserted at the beginning of the segment list,
793 depending on its offset, we have to force a final pass through the
794 loop by demanding that completion sees a pass with no matches; ie.
795 all symbols with equiv_built set and no new equivalences found. */
6de9cd9a 796
5291e69a 797static void
a3122424 798add_equivalences (bool *saw_equiv)
6de9cd9a 799{
6de9cd9a 800 segment_info *f;
8a0b57b3 801 bool seen_one, more;
6de9cd9a 802
8a0b57b3 803 seen_one = false;
5291e69a
PB
804 more = TRUE;
805 while (more)
6de9cd9a 806 {
5291e69a
PB
807 more = FALSE;
808 for (f = current_segment; f; f = f->next)
809 {
810 if (!f->sym->equiv_built)
811 {
812 f->sym->equiv_built = 1;
8a0b57b3
PT
813 seen_one = find_equivalence (f);
814 if (seen_one)
815 {
816 *saw_equiv = true;
817 more = true;
818 }
5291e69a
PB
819 }
820 }
6de9cd9a 821 }
61321991
PT
822
823 /* Add a copy of this segment list to the namespace. */
824 copy_equiv_list_to_ns (current_segment);
6de9cd9a 825}
a8a6b603
TS
826
827
43a5ef69 828/* Returns the offset necessary to properly align the current equivalence.
832ef1ce
PB
829 Sets *palign to the required alignment. */
830
831static HOST_WIDE_INT
66e4ab31 832align_segment (unsigned HOST_WIDE_INT *palign)
832ef1ce
PB
833{
834 segment_info *s;
835 unsigned HOST_WIDE_INT offset;
836 unsigned HOST_WIDE_INT max_align;
837 unsigned HOST_WIDE_INT this_align;
838 unsigned HOST_WIDE_INT this_offset;
839
840 max_align = 1;
841 offset = 0;
842 for (s = current_segment; s; s = s->next)
843 {
844 this_align = TYPE_ALIGN_UNIT (s->field);
845 if (s->offset & (this_align - 1))
846 {
847 /* Field is misaligned. */
848 this_offset = this_align - ((s->offset + offset) & (this_align - 1));
849 if (this_offset & (max_align - 1))
850 {
851 /* Aligning this field would misalign a previous field. */
852 gfc_error ("The equivalence set for variable '%s' "
eb6d74fa 853 "declared at %L violates alignment requirements",
832ef1ce
PB
854 s->sym->name, &s->sym->declared_at);
855 }
856 offset += this_offset;
857 }
858 max_align = this_align;
859 }
860 if (palign)
861 *palign = max_align;
862 return offset;
863}
864
865
866/* Adjust segment offsets by the given amount. */
a8a6b603 867
6de9cd9a 868static void
66e4ab31 869apply_segment_offset (segment_info *s, HOST_WIDE_INT offset)
6de9cd9a 870{
832ef1ce
PB
871 for (; s; s = s->next)
872 s->offset += offset;
873}
874
875
876/* Lay out a symbol in a common block. If the symbol has already been seen
877 then check the location is consistent. Otherwise create segments
878 for that symbol and all the symbols equivalenced with it. */
879
880/* Translate a single common block. */
881
882static void
883translate_common (gfc_common_head *common, gfc_symbol *var_list)
884{
885 gfc_symbol *sym;
886 segment_info *s;
887 segment_info *common_segment;
888 HOST_WIDE_INT offset;
889 HOST_WIDE_INT current_offset;
890 unsigned HOST_WIDE_INT align;
891 unsigned HOST_WIDE_INT max_align;
a3122424 892 bool saw_equiv;
832ef1ce
PB
893
894 common_segment = NULL;
895 current_offset = 0;
896 max_align = 1;
a3122424 897 saw_equiv = false;
832ef1ce
PB
898
899 /* Add symbols to the segment. */
900 for (sym = var_list; sym; sym = sym->common_next)
901 {
30aabb86
PT
902 current_segment = common_segment;
903 s = find_segment_info (sym);
832ef1ce 904
30aabb86
PT
905 /* Symbol has already been added via an equivalence. Multiple
906 use associations of the same common block result in equiv_built
907 being set but no information about the symbol in the segment. */
908 if (s && sym->equiv_built)
909 {
832ef1ce
PB
910 /* Ensure the current location is properly aligned. */
911 align = TYPE_ALIGN_UNIT (s->field);
912 current_offset = (current_offset + align - 1) &~ (align - 1);
913
914 /* Verify that it ended up where we expect it. */
915 if (s->offset != current_offset)
916 {
917 gfc_error ("Equivalence for '%s' does not match ordering of "
918 "COMMON '%s' at %L", sym->name,
919 common->name, &common->where);
920 }
921 }
922 else
923 {
924 /* A symbol we haven't seen before. */
925 s = current_segment = get_segment_info (sym, current_offset);
a8a6b603 926
832ef1ce
PB
927 /* Add all objects directly or indirectly equivalenced with this
928 symbol. */
a3122424 929 add_equivalences (&saw_equiv);
ad6e2a18 930
832ef1ce
PB
931 if (current_segment->offset < 0)
932 gfc_error ("The equivalence set for '%s' cause an invalid "
933 "extension to COMMON '%s' at %L", sym->name,
934 common->name, &common->where);
6de9cd9a 935
832ef1ce 936 offset = align_segment (&align);
6de9cd9a 937
832ef1ce
PB
938 if (offset & (max_align - 1))
939 {
940 /* The required offset conflicts with previous alignment
941 requirements. Insert padding immediately before this
942 segment. */
943 gfc_warning ("Padding of %d bytes required before '%s' in "
eb83e811 944 "COMMON '%s' at %L", (int)offset, s->sym->name,
832ef1ce
PB
945 common->name, &common->where);
946 }
947 else
948 {
949 /* Offset the whole common block. */
950 apply_segment_offset (common_segment, offset);
951 }
6de9cd9a 952
832ef1ce
PB
953 /* Apply the offset to the new segments. */
954 apply_segment_offset (current_segment, offset);
955 current_offset += offset;
956 if (max_align < align)
957 max_align = align;
958
959 /* Add the new segments to the common block. */
960 common_segment = add_segments (common_segment, current_segment);
961 }
962
963 /* The offset of the next common variable. */
964 current_offset += s->length;
965 }
966
b8ea6dbc
PT
967 if (common_segment == NULL)
968 {
969 gfc_error ("COMMON '%s' at %L does not exist",
970 common->name, &common->where);
971 return;
972 }
973
832ef1ce
PB
974 if (common_segment->offset != 0)
975 {
976 gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start",
eb83e811 977 common->name, &common->where, (int)common_segment->offset);
832ef1ce
PB
978 }
979
a3122424 980 create_common (common, common_segment, saw_equiv);
6de9cd9a
DN
981}
982
983
984/* Create a new block for each merged equivalence list. */
985
986static void
987finish_equivalences (gfc_namespace *ns)
988{
989 gfc_equiv *z, *y;
990 gfc_symbol *sym;
30aabb86 991 gfc_common_head * c;
36c028f6
PB
992 HOST_WIDE_INT offset;
993 unsigned HOST_WIDE_INT align;
a3122424 994 bool dummy;
6de9cd9a
DN
995
996 for (z = ns->equiv; z; z = z->next)
a8a6b603 997 for (y = z->eq; y; y = y->eq)
6de9cd9a 998 {
a8a6b603
TS
999 if (y->used)
1000 continue;
6de9cd9a 1001 sym = z->expr->symtree->n.sym;
ad6e2a18 1002 current_segment = get_segment_info (sym, 0);
6de9cd9a 1003
66e4ab31
SK
1004 /* All objects directly or indirectly equivalenced with this
1005 symbol. */
a3122424 1006 add_equivalences (&dummy);
6de9cd9a 1007
36c028f6
PB
1008 /* Align the block. */
1009 offset = align_segment (&align);
832ef1ce 1010
36c028f6
PB
1011 /* Ensure all offsets are positive. */
1012 offset -= current_segment->offset & ~(align - 1);
6de9cd9a 1013
36c028f6 1014 apply_segment_offset (current_segment, offset);
6de9cd9a 1015
66e4ab31
SK
1016 /* Create the decl. If this is a module equivalence, it has a
1017 unique name, pointed to by z->module. This is written to a
1018 gfc_common_header to push create_common into using
1019 build_common_decl, so that the equivalence appears as an
1020 external symbol. Otherwise, a local declaration is built using
1021 build_equiv_decl. */
30aabb86
PT
1022 if (z->module)
1023 {
1024 c = gfc_get_common_head ();
1025 /* We've lost the real location, so use the location of the
66e4ab31 1026 enclosing procedure. */
30aabb86
PT
1027 c->where = ns->proc_name->declared_at;
1028 strcpy (c->name, z->module);
1029 }
1030 else
1031 c = NULL;
1032
1033 create_common (c, current_segment, true);
6de9cd9a
DN
1034 break;
1035 }
1036}
1037
1038
6de9cd9a
DN
1039/* Work function for translating a named common block. */
1040
1041static void
9056bd70 1042named_common (gfc_symtree *st)
6de9cd9a 1043{
53814b8f 1044 translate_common (st->n.common, st->n.common->head);
6de9cd9a
DN
1045}
1046
1047
1048/* Translate the common blocks in a namespace. Unlike other variables,
1049 these have to be created before code, because the backend_decl depends
1050 on the rest of the common block. */
a8a6b603
TS
1051
1052void
6de9cd9a
DN
1053gfc_trans_common (gfc_namespace *ns)
1054{
9056bd70 1055 gfc_common_head *c;
6de9cd9a
DN
1056
1057 /* Translate the blank common block. */
9056bd70 1058 if (ns->blank_common.head != NULL)
6de9cd9a 1059 {
9056bd70 1060 c = gfc_get_common_head ();
41433497 1061
c8cc8542
PB
1062 /* We've lost the real location, so use the location of the
1063 enclosing procedure. */
41433497
BF
1064 if (ns->proc_name != NULL)
1065 c->where = ns->proc_name->declared_at;
1066 else
1067 c->where = ns->blank_common.head->common_head->where;
1068
53814b8f
TS
1069 strcpy (c->name, BLANK_COMMON_NAME);
1070 translate_common (c, ns->blank_common.head);
6de9cd9a 1071 }
41433497 1072
6de9cd9a 1073 /* Translate all named common blocks. */
a8a6b603 1074 gfc_traverse_symtree (ns->common_root, named_common);
6de9cd9a 1075
6de9cd9a
DN
1076 /* Translate local equivalence. */
1077 finish_equivalences (ns);
613e2ac8
PT
1078
1079 /* Commit the newly created symbols for common blocks and module
1080 equivalences. */
1081 gfc_commit_symbols ();
6de9cd9a 1082}
This page took 0.930026 seconds and 5 git commands to generate.