]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/fortran/array.c
Make-lang.in, [...]: Update copyright years and boilerplate.
[thirdparty/gcc.git] / gcc / fortran / array.c
1 /* Array things
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4
5 This file is part of GCC.
6
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.
11
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.
16
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. */
21
22 #include "config.h"
23 #include "gfortran.h"
24 #include "match.h"
25
26 #include <string.h>
27 #include <assert.h>
28
29 /* This parameter is the size of the largest array constructor that we
30 will expand to an array constructor without iterators.
31 Constructors larger than this will remain in the iterator form. */
32
33 #define GFC_MAX_AC_EXPAND 100
34
35
36 /**************** Array reference matching subroutines *****************/
37
38 /* Copy an array reference structure. */
39
40 gfc_array_ref *
41 gfc_copy_array_ref (gfc_array_ref * src)
42 {
43 gfc_array_ref *dest;
44 int i;
45
46 if (src == NULL)
47 return NULL;
48
49 dest = gfc_get_array_ref ();
50
51 *dest = *src;
52
53 for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
54 {
55 dest->start[i] = gfc_copy_expr (src->start[i]);
56 dest->end[i] = gfc_copy_expr (src->end[i]);
57 dest->stride[i] = gfc_copy_expr (src->stride[i]);
58 }
59
60 dest->offset = gfc_copy_expr (src->offset);
61
62 return dest;
63 }
64
65
66 /* Match a single dimension of an array reference. This can be a
67 single element or an array section. Any modifications we've made
68 to the ar structure are cleaned up by the caller. If the init
69 is set, we require the subscript to be a valid initialization
70 expression. */
71
72 static match
73 match_subscript (gfc_array_ref * ar, int init)
74 {
75 match m;
76 int i;
77
78 i = ar->dimen;
79
80 ar->c_where[i] = *gfc_current_locus ();
81 ar->start[i] = ar->end[i] = ar->stride[i] = NULL;
82
83 /* We can't be sure of the difference between DIMEN_ELEMENT and
84 DIMEN_VECTOR until we know the type of the element itself at
85 resolution time. */
86
87 ar->dimen_type[i] = DIMEN_UNKNOWN;
88
89 if (gfc_match_char (':') == MATCH_YES)
90 goto end_element;
91
92 /* Get start element. */
93 if (init)
94 m = gfc_match_init_expr (&ar->start[i]);
95 else
96 m = gfc_match_expr (&ar->start[i]);
97
98 if (m == MATCH_NO)
99 gfc_error ("Expected array subscript at %C");
100 if (m != MATCH_YES)
101 return MATCH_ERROR;
102
103 if (gfc_match_char (':') == MATCH_NO)
104 return MATCH_YES;
105
106 /* Get an optional end element. Because we've seen the colon, we
107 definitely have a range along this dimension. */
108 end_element:
109 ar->dimen_type[i] = DIMEN_RANGE;
110
111 if (init)
112 m = gfc_match_init_expr (&ar->end[i]);
113 else
114 m = gfc_match_expr (&ar->end[i]);
115
116 if (m == MATCH_ERROR)
117 return MATCH_ERROR;
118
119 /* See if we have an optional stride. */
120 if (gfc_match_char (':') == MATCH_YES)
121 {
122 m = init ? gfc_match_init_expr (&ar->stride[i])
123 : gfc_match_expr (&ar->stride[i]);
124
125 if (m == MATCH_NO)
126 gfc_error ("Expected array subscript stride at %C");
127 if (m != MATCH_YES)
128 return MATCH_ERROR;
129 }
130
131 return MATCH_YES;
132 }
133
134
135 /* Match an array reference, whether it is the whole array or a
136 particular elements or a section. If init is set, the reference has
137 to consist of init expressions. */
138
139 match
140 gfc_match_array_ref (gfc_array_ref * ar, gfc_array_spec * as, int init)
141 {
142 match m;
143
144 memset (ar, '\0', sizeof (ar));
145
146 ar->where = *gfc_current_locus ();
147 ar->as = as;
148
149 if (gfc_match_char ('(') != MATCH_YES)
150 {
151 ar->type = AR_FULL;
152 ar->dimen = 0;
153 return MATCH_YES;
154 }
155
156 ar->type = AR_UNKNOWN;
157
158 for (ar->dimen = 0; ar->dimen < GFC_MAX_DIMENSIONS; ar->dimen++)
159 {
160 m = match_subscript (ar, init);
161 if (m == MATCH_ERROR)
162 goto error;
163
164 if (gfc_match_char (')') == MATCH_YES)
165 goto matched;
166
167 if (gfc_match_char (',') != MATCH_YES)
168 {
169 gfc_error ("Invalid form of array reference at %C");
170 goto error;
171 }
172 }
173
174 gfc_error ("Array reference at %C cannot have more than "
175 stringize (GFC_MAX_DIMENSIONS) " dimensions");
176
177 error:
178 return MATCH_ERROR;
179
180 matched:
181 ar->dimen++;
182
183 return MATCH_YES;
184 }
185
186
187 /************** Array specification matching subroutines ***************/
188
189 /* Free all of the expressions associated with array bounds
190 specifications. */
191
192 void
193 gfc_free_array_spec (gfc_array_spec * as)
194 {
195 int i;
196
197 if (as == NULL)
198 return;
199
200 for (i = 0; i < as->rank; i++)
201 {
202 gfc_free_expr (as->lower[i]);
203 gfc_free_expr (as->upper[i]);
204 }
205
206 gfc_free (as);
207 }
208
209
210 /* Take an array bound, resolves the expression, that make up the
211 shape and check associated constraints. */
212
213 static try
214 resolve_array_bound (gfc_expr * e, int check_constant)
215 {
216
217 if (e == NULL)
218 return SUCCESS;
219
220 if (gfc_resolve_expr (e) == FAILURE
221 || gfc_specification_expr (e) == FAILURE)
222 return FAILURE;
223
224 if (check_constant && gfc_is_constant_expr (e) == 0)
225 {
226 gfc_error ("Variable '%s' at %L in this context must be constant",
227 e->symtree->n.sym->name, &e->where);
228 return FAILURE;
229 }
230
231 return SUCCESS;
232 }
233
234
235 /* Takes an array specification, resolves the expressions that make up
236 the shape and make sure everything is integral. */
237
238 try
239 gfc_resolve_array_spec (gfc_array_spec * as, int check_constant)
240 {
241 gfc_expr *e;
242 int i;
243
244 if (as == NULL)
245 return SUCCESS;
246
247 for (i = 0; i < as->rank; i++)
248 {
249 e = as->lower[i];
250 if (resolve_array_bound (e, check_constant) == FAILURE)
251 return FAILURE;
252
253 e = as->upper[i];
254 if (resolve_array_bound (e, check_constant) == FAILURE)
255 return FAILURE;
256 }
257
258 return SUCCESS;
259 }
260
261
262 /* Match a single array element specification. The return values as
263 well as the upper and lower bounds of the array spec are filled
264 in according to what we see on the input. The caller makes sure
265 individual specifications make sense as a whole.
266
267
268 Parsed Lower Upper Returned
269 ------------------------------------
270 : NULL NULL AS_DEFERRED (*)
271 x 1 x AS_EXPLICIT
272 x: x NULL AS_ASSUMED_SHAPE
273 x:y x y AS_EXPLICIT
274 x:* x NULL AS_ASSUMED_SIZE
275 * 1 NULL AS_ASSUMED_SIZE
276
277 (*) For non-pointer dummy arrays this is AS_ASSUMED_SHAPE. This
278 is fixed during the resolution of formal interfaces.
279
280 Anything else AS_UNKNOWN. */
281
282 static array_type
283 match_array_element_spec (gfc_array_spec * as)
284 {
285 gfc_expr **upper, **lower;
286 match m;
287
288 lower = &as->lower[as->rank - 1];
289 upper = &as->upper[as->rank - 1];
290
291 if (gfc_match_char ('*') == MATCH_YES)
292 {
293 *lower = gfc_int_expr (1);
294 return AS_ASSUMED_SIZE;
295 }
296
297 if (gfc_match_char (':') == MATCH_YES)
298 return AS_DEFERRED;
299
300 m = gfc_match_expr (upper);
301 if (m == MATCH_NO)
302 gfc_error ("Expected expression in array specification at %C");
303 if (m != MATCH_YES)
304 return AS_UNKNOWN;
305
306 if (gfc_match_char (':') == MATCH_NO)
307 {
308 *lower = gfc_int_expr (1);
309 return AS_EXPLICIT;
310 }
311
312 *lower = *upper;
313 *upper = NULL;
314
315 if (gfc_match_char ('*') == MATCH_YES)
316 return AS_ASSUMED_SIZE;
317
318 m = gfc_match_expr (upper);
319 if (m == MATCH_ERROR)
320 return AS_UNKNOWN;
321 if (m == MATCH_NO)
322 return AS_ASSUMED_SHAPE;
323
324 return AS_EXPLICIT;
325 }
326
327
328 /* Matches an array specification, incidentally figuring out what sort
329 it is. */
330
331 match
332 gfc_match_array_spec (gfc_array_spec ** asp)
333 {
334 array_type current_type;
335 gfc_array_spec *as;
336 int i;
337
338 if (gfc_match_char ('(') != MATCH_YES)
339 {
340 *asp = NULL;
341 return MATCH_NO;
342 }
343
344 as = gfc_get_array_spec ();
345
346 for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
347 {
348 as->lower[i] = NULL;
349 as->upper[i] = NULL;
350 }
351
352 as->rank = 1;
353
354 for (;;)
355 {
356 current_type = match_array_element_spec (as);
357
358 if (as->rank == 1)
359 {
360 if (current_type == AS_UNKNOWN)
361 goto cleanup;
362 as->type = current_type;
363 }
364 else
365 switch (as->type)
366 { /* See how current spec meshes with the existing */
367 case AS_UNKNOWN:
368 goto cleanup;
369
370 case AS_EXPLICIT:
371 if (current_type == AS_ASSUMED_SIZE)
372 {
373 as->type = AS_ASSUMED_SIZE;
374 break;
375 }
376
377 if (current_type == AS_EXPLICIT)
378 break;
379
380 gfc_error
381 ("Bad array specification for an explicitly shaped array"
382 " at %C");
383
384 goto cleanup;
385
386 case AS_ASSUMED_SHAPE:
387 if ((current_type == AS_ASSUMED_SHAPE)
388 || (current_type == AS_DEFERRED))
389 break;
390
391 gfc_error
392 ("Bad array specification for assumed shape array at %C");
393 goto cleanup;
394
395 case AS_DEFERRED:
396 if (current_type == AS_DEFERRED)
397 break;
398
399 if (current_type == AS_ASSUMED_SHAPE)
400 {
401 as->type = AS_ASSUMED_SHAPE;
402 break;
403 }
404
405 gfc_error ("Bad specification for deferred shape array at %C");
406 goto cleanup;
407
408 case AS_ASSUMED_SIZE:
409 gfc_error ("Bad specification for assumed size array at %C");
410 goto cleanup;
411 }
412
413 if (gfc_match_char (')') == MATCH_YES)
414 break;
415
416 if (gfc_match_char (',') != MATCH_YES)
417 {
418 gfc_error ("Expected another dimension in array declaration at %C");
419 goto cleanup;
420 }
421
422 if (as->rank >= GFC_MAX_DIMENSIONS)
423 {
424 gfc_error ("Array specification at %C has more than "
425 stringize (GFC_MAX_DIMENSIONS) " dimensions");
426 goto cleanup;
427 }
428
429 as->rank++;
430 }
431
432 /* If a lower bounds of an assumed shape array is blank, put in one. */
433 if (as->type == AS_ASSUMED_SHAPE)
434 {
435 for (i = 0; i < as->rank; i++)
436 {
437 if (as->lower[i] == NULL)
438 as->lower[i] = gfc_int_expr (1);
439 }
440 }
441 *asp = as;
442 return MATCH_YES;
443
444 cleanup:
445 /* Something went wrong. */
446 gfc_free_array_spec (as);
447 return MATCH_ERROR;
448 }
449
450
451 /* Given a symbol and an array specification, modify the symbol to
452 have that array specification. The error locus is needed in case
453 something goes wrong. On failure, the caller must free the spec. */
454
455 try
456 gfc_set_array_spec (gfc_symbol * sym, gfc_array_spec * as, locus * error_loc)
457 {
458
459 if (as == NULL)
460 return SUCCESS;
461
462 if (gfc_add_dimension (&sym->attr, error_loc) == FAILURE)
463 return FAILURE;
464
465 sym->as = as;
466
467 return SUCCESS;
468 }
469
470
471 /* Copy an array specification. */
472
473 gfc_array_spec *
474 gfc_copy_array_spec (gfc_array_spec * src)
475 {
476 gfc_array_spec *dest;
477 int i;
478
479 if (src == NULL)
480 return NULL;
481
482 dest = gfc_get_array_spec ();
483
484 *dest = *src;
485
486 for (i = 0; i < dest->rank; i++)
487 {
488 dest->lower[i] = gfc_copy_expr (dest->lower[i]);
489 dest->upper[i] = gfc_copy_expr (dest->upper[i]);
490 }
491
492 return dest;
493 }
494
495 /* Returns nonzero if the two expressions are equal. Only handles integer
496 constants. */
497
498 static int
499 compare_bounds (gfc_expr * bound1, gfc_expr * bound2)
500 {
501 if (bound1 == NULL || bound2 == NULL
502 || bound1->expr_type != EXPR_CONSTANT
503 || bound2->expr_type != EXPR_CONSTANT
504 || bound1->ts.type != BT_INTEGER
505 || bound2->ts.type != BT_INTEGER)
506 gfc_internal_error ("gfc_compare_array_spec(): Array spec clobbered");
507
508 if (mpz_cmp (bound1->value.integer, bound2->value.integer) == 0)
509 return 1;
510 else
511 return 0;
512 }
513
514 /* Compares two array specifications. They must be constant or deferred
515 shape. */
516
517 int
518 gfc_compare_array_spec (gfc_array_spec * as1, gfc_array_spec * as2)
519 {
520 int i;
521
522 if (as1 == NULL && as2 == NULL)
523 return 1;
524
525 if (as1 == NULL || as2 == NULL)
526 return 0;
527
528 if (as1->rank != as2->rank)
529 return 0;
530
531 if (as1->rank == 0)
532 return 1;
533
534 if (as1->type != as2->type)
535 return 0;
536
537 if (as1->type == AS_EXPLICIT)
538 for (i = 0; i < as1->rank; i++)
539 {
540 if (compare_bounds (as1->lower[i], as2->lower[i]) == 0)
541 return 0;
542
543 if (compare_bounds (as1->upper[i], as2->upper[i]) == 0)
544 return 0;
545 }
546
547 return 1;
548 }
549
550
551 /****************** Array constructor functions ******************/
552
553 /* Start an array constructor. The constructor starts with zero
554 elements and should be appended to by gfc_append_constructor(). */
555
556 gfc_expr *
557 gfc_start_constructor (bt type, int kind, locus * where)
558 {
559 gfc_expr *result;
560
561 result = gfc_get_expr ();
562
563 result->expr_type = EXPR_ARRAY;
564 result->rank = 1;
565
566 result->ts.type = type;
567 result->ts.kind = kind;
568 result->where = *where;
569 return result;
570 }
571
572
573 /* Given an array constructor expression, append the new expression
574 node onto the constructor. */
575
576 void
577 gfc_append_constructor (gfc_expr * base, gfc_expr * new)
578 {
579 gfc_constructor *c;
580
581 if (base->value.constructor == NULL)
582 base->value.constructor = c = gfc_get_constructor ();
583 else
584 {
585 c = base->value.constructor;
586 while (c->next)
587 c = c->next;
588
589 c->next = gfc_get_constructor ();
590 c = c->next;
591 }
592
593 c->expr = new;
594
595 if (new->ts.type != base->ts.type || new->ts.kind != base->ts.kind)
596 gfc_internal_error ("gfc_append_constructor(): New node has wrong kind");
597 }
598
599
600 /* Given an array constructor expression, insert the new expression's
601 constructor onto the base's one according to the offset. */
602
603 void
604 gfc_insert_constructor (gfc_expr * base, gfc_constructor * c1)
605 {
606 gfc_constructor *c, *pre;
607 expr_t type;
608
609 type = base->expr_type;
610
611 if (base->value.constructor == NULL)
612 base->value.constructor = c1;
613 else
614 {
615 c = pre = base->value.constructor;
616 while (c)
617 {
618 if (type == EXPR_ARRAY)
619 {
620 if (mpz_cmp (c->n.offset, c1->n.offset) < 0)
621 {
622 pre = c;
623 c = c->next;
624 }
625 else if (mpz_cmp (c->n.offset, c1->n.offset) == 0)
626 {
627 gfc_error ("duplicated initializer");
628 break;
629 }
630 else
631 break;
632 }
633 else
634 {
635 pre = c;
636 c = c->next;
637 }
638 }
639
640 if (pre != c)
641 {
642 pre->next = c1;
643 c1->next = c;
644 }
645 else
646 {
647 c1->next = c;
648 base->value.constructor = c1;
649 }
650 }
651 }
652
653
654 /* Get a new constructor. */
655
656 gfc_constructor *
657 gfc_get_constructor (void)
658 {
659 gfc_constructor *c;
660
661 c = gfc_getmem (sizeof(gfc_constructor));
662 c->expr = NULL;
663 c->iterator = NULL;
664 c->next = NULL;
665 mpz_init_set_si (c->n.offset, 0);
666 mpz_init_set_si (c->repeat, 0);
667 return c;
668 }
669
670
671 /* Free chains of gfc_constructor structures. */
672
673 void
674 gfc_free_constructor (gfc_constructor * p)
675 {
676 gfc_constructor *next;
677
678 if (p == NULL)
679 return;
680
681 for (; p; p = next)
682 {
683 next = p->next;
684
685 if (p->expr)
686 gfc_free_expr (p->expr);
687 if (p->iterator != NULL)
688 gfc_free_iterator (p->iterator, 1);
689 mpz_clear (p->n.offset);
690 mpz_clear (p->repeat);
691 gfc_free (p);
692 }
693 }
694
695
696 /* Given an expression node that might be an array constructor and a
697 symbol, make sure that no iterators in this or child constructors
698 use the symbol as an implied-DO iterator. Returns nonzero if a
699 duplicate was found. */
700
701 static int
702 check_duplicate_iterator (gfc_constructor * c, gfc_symbol * master)
703 {
704 gfc_expr *e;
705
706 for (; c; c = c->next)
707 {
708 e = c->expr;
709
710 if (e->expr_type == EXPR_ARRAY
711 && check_duplicate_iterator (e->value.constructor, master))
712 return 1;
713
714 if (c->iterator == NULL)
715 continue;
716
717 if (c->iterator->var->symtree->n.sym == master)
718 {
719 gfc_error
720 ("DO-iterator '%s' at %L is inside iterator of the same name",
721 master->name, &c->where);
722
723 return 1;
724 }
725 }
726
727 return 0;
728 }
729
730
731 /* Forward declaration because these functions are mutually recursive. */
732 static match match_array_cons_element (gfc_constructor **);
733
734 /* Match a list of array elements. */
735
736 static match
737 match_array_list (gfc_constructor ** result)
738 {
739 gfc_constructor *p, *head, *tail, *new;
740 gfc_iterator iter;
741 locus old_loc;
742 gfc_expr *e;
743 match m;
744 int n;
745
746 old_loc = *gfc_current_locus ();
747
748 if (gfc_match_char ('(') == MATCH_NO)
749 return MATCH_NO;
750
751 memset (&iter, '\0', sizeof (gfc_iterator));
752 head = NULL;
753
754 m = match_array_cons_element (&head);
755 if (m != MATCH_YES)
756 goto cleanup;
757
758 tail = head;
759
760 if (gfc_match_char (',') != MATCH_YES)
761 {
762 m = MATCH_NO;
763 goto cleanup;
764 }
765
766 for (n = 1;; n++)
767 {
768 m = gfc_match_iterator (&iter, 0);
769 if (m == MATCH_YES)
770 break;
771 if (m == MATCH_ERROR)
772 goto cleanup;
773
774 m = match_array_cons_element (&new);
775 if (m == MATCH_ERROR)
776 goto cleanup;
777 if (m == MATCH_NO)
778 {
779 if (n > 2)
780 goto syntax;
781 m = MATCH_NO;
782 goto cleanup; /* Could be a complex constant */
783 }
784
785 tail->next = new;
786 tail = new;
787
788 if (gfc_match_char (',') != MATCH_YES)
789 {
790 if (n > 2)
791 goto syntax;
792 m = MATCH_NO;
793 goto cleanup;
794 }
795 }
796
797 if (gfc_match_char (')') != MATCH_YES)
798 goto syntax;
799
800 if (check_duplicate_iterator (head, iter.var->symtree->n.sym))
801 {
802 m = MATCH_ERROR;
803 goto cleanup;
804 }
805
806 e = gfc_get_expr ();
807 e->expr_type = EXPR_ARRAY;
808 e->where = old_loc;
809 e->value.constructor = head;
810
811 p = gfc_get_constructor ();
812 p->where = *gfc_current_locus ();
813 p->iterator = gfc_get_iterator ();
814 *p->iterator = iter;
815
816 p->expr = e;
817 *result = p;
818
819 return MATCH_YES;
820
821 syntax:
822 gfc_error ("Syntax error in array constructor at %C");
823 m = MATCH_ERROR;
824
825 cleanup:
826 gfc_free_constructor (head);
827 gfc_free_iterator (&iter, 0);
828 gfc_set_locus (&old_loc);
829 return m;
830 }
831
832
833 /* Match a single element of an array constructor, which can be a
834 single expression or a list of elements. */
835
836 static match
837 match_array_cons_element (gfc_constructor ** result)
838 {
839 gfc_constructor *p;
840 gfc_expr *expr;
841 match m;
842
843 m = match_array_list (result);
844 if (m != MATCH_NO)
845 return m;
846
847 m = gfc_match_expr (&expr);
848 if (m != MATCH_YES)
849 return m;
850
851 p = gfc_get_constructor ();
852 p->where = *gfc_current_locus ();
853 p->expr = expr;
854
855 *result = p;
856 return MATCH_YES;
857 }
858
859
860 /* Match an array constructor. */
861
862 match
863 gfc_match_array_constructor (gfc_expr ** result)
864 {
865 gfc_constructor *head, *tail, *new;
866 gfc_expr *expr;
867 locus where;
868 match m;
869
870 if (gfc_match (" (/") == MATCH_NO)
871 return MATCH_NO;
872
873 where = *gfc_current_locus ();
874 head = tail = NULL;
875
876 if (gfc_match (" /)") == MATCH_YES)
877 goto empty; /* Special case */
878
879 for (;;)
880 {
881 m = match_array_cons_element (&new);
882 if (m == MATCH_ERROR)
883 goto cleanup;
884 if (m == MATCH_NO)
885 goto syntax;
886
887 if (head == NULL)
888 head = new;
889 else
890 tail->next = new;
891
892 tail = new;
893
894 if (gfc_match_char (',') == MATCH_NO)
895 break;
896 }
897
898 if (gfc_match (" /)") == MATCH_NO)
899 goto syntax;
900
901 empty:
902 expr = gfc_get_expr ();
903
904 expr->expr_type = EXPR_ARRAY;
905
906 expr->value.constructor = head;
907 /* Size must be calculated at resolution time. */
908
909 expr->where = where;
910 expr->rank = 1;
911
912 *result = expr;
913 return MATCH_YES;
914
915 syntax:
916 gfc_error ("Syntax error in array constructor at %C");
917
918 cleanup:
919 gfc_free_constructor (head);
920 return MATCH_ERROR;
921 }
922
923
924
925 /************** Check array constructors for correctness **************/
926
927 /* Given an expression, compare it's type with the type of the current
928 constructor. Returns nonzero if an error was issued. The
929 cons_state variable keeps track of whether the type of the
930 constructor being read or resolved is known to be good, bad or just
931 starting out. */
932
933 static gfc_typespec constructor_ts;
934 static enum
935 { CONS_START, CONS_GOOD, CONS_BAD }
936 cons_state;
937
938 static int
939 check_element_type (gfc_expr * expr)
940 {
941
942 if (cons_state == CONS_BAD)
943 return 0; /* Supress further errors */
944
945 if (cons_state == CONS_START)
946 {
947 if (expr->ts.type == BT_UNKNOWN)
948 cons_state = CONS_BAD;
949 else
950 {
951 cons_state = CONS_GOOD;
952 constructor_ts = expr->ts;
953 }
954
955 return 0;
956 }
957
958 if (gfc_compare_types (&constructor_ts, &expr->ts))
959 return 0;
960
961 gfc_error ("Element in %s array constructor at %L is %s",
962 gfc_typename (&constructor_ts), &expr->where,
963 gfc_typename (&expr->ts));
964
965 cons_state = CONS_BAD;
966 return 1;
967 }
968
969
970 /* Recursive work function for gfc_check_constructor_type(). */
971
972 static try
973 check_constructor_type (gfc_constructor * c)
974 {
975 gfc_expr *e;
976
977 for (; c; c = c->next)
978 {
979 e = c->expr;
980
981 if (e->expr_type == EXPR_ARRAY)
982 {
983 if (check_constructor_type (e->value.constructor) == FAILURE)
984 return FAILURE;
985
986 continue;
987 }
988
989 if (check_element_type (e))
990 return FAILURE;
991 }
992
993 return SUCCESS;
994 }
995
996
997 /* Check that all elements of an array constructor are the same type.
998 On FAILURE, an error has been generated. */
999
1000 try
1001 gfc_check_constructor_type (gfc_expr * e)
1002 {
1003 try t;
1004
1005 cons_state = CONS_START;
1006 gfc_clear_ts (&constructor_ts);
1007
1008 t = check_constructor_type (e->value.constructor);
1009 if (t == SUCCESS && e->ts.type == BT_UNKNOWN)
1010 e->ts = constructor_ts;
1011
1012 return t;
1013 }
1014
1015
1016
1017 typedef struct cons_stack
1018 {
1019 gfc_iterator *iterator;
1020 struct cons_stack *previous;
1021 }
1022 cons_stack;
1023
1024 static cons_stack *base;
1025
1026 static try check_constructor (gfc_constructor *, try (*)(gfc_expr *));
1027
1028 /* Check an EXPR_VARIABLE expression in a constructor to make sure
1029 that that variable is an iteration variables. */
1030
1031 try
1032 gfc_check_iter_variable (gfc_expr * expr)
1033 {
1034
1035 gfc_symbol *sym;
1036 cons_stack *c;
1037
1038 sym = expr->symtree->n.sym;
1039
1040 for (c = base; c; c = c->previous)
1041 if (sym == c->iterator->var->symtree->n.sym)
1042 return SUCCESS;
1043
1044 return FAILURE;
1045 }
1046
1047
1048 /* Recursive work function for gfc_check_constructor(). This amounts
1049 to calling the check function for each expression in the
1050 constructor, giving variables with the names of iterators a pass. */
1051
1052 static try
1053 check_constructor (gfc_constructor * c, try (*check_function) (gfc_expr *))
1054 {
1055 cons_stack element;
1056 gfc_expr *e;
1057 try t;
1058
1059 for (; c; c = c->next)
1060 {
1061 e = c->expr;
1062
1063 if (e->expr_type != EXPR_ARRAY)
1064 {
1065 if ((*check_function) (e) == FAILURE)
1066 return FAILURE;
1067 continue;
1068 }
1069
1070 element.previous = base;
1071 element.iterator = c->iterator;
1072
1073 base = &element;
1074 t = check_constructor (e->value.constructor, check_function);
1075 base = element.previous;
1076
1077 if (t == FAILURE)
1078 return FAILURE;
1079 }
1080
1081 /* Nothing went wrong, so all OK. */
1082 return SUCCESS;
1083 }
1084
1085
1086 /* Checks a constructor to see if it is a particular kind of
1087 expression -- specification, restricted, or initialization as
1088 determined by the check_function. */
1089
1090 try
1091 gfc_check_constructor (gfc_expr * expr, try (*check_function) (gfc_expr *))
1092 {
1093 cons_stack *base_save;
1094 try t;
1095
1096 base_save = base;
1097 base = NULL;
1098
1099 t = check_constructor (expr->value.constructor, check_function);
1100 base = base_save;
1101
1102 return t;
1103 }
1104
1105
1106
1107 /**************** Simplification of array constructors ****************/
1108
1109 iterator_stack *iter_stack;
1110
1111 typedef struct
1112 {
1113 gfc_constructor *new_head, *new_tail;
1114 int extract_count, extract_n;
1115 gfc_expr *extracted;
1116 mpz_t *count;
1117
1118 mpz_t *offset;
1119 gfc_component *component;
1120 mpz_t *repeat;
1121
1122 try (*expand_work_function) (gfc_expr *);
1123 }
1124 expand_info;
1125
1126 static expand_info current_expand;
1127
1128 static try expand_constructor (gfc_constructor *);
1129
1130
1131 /* Work function that counts the number of elements present in a
1132 constructor. */
1133
1134 static try
1135 count_elements (gfc_expr * e)
1136 {
1137 mpz_t result;
1138
1139 if (e->rank == 0)
1140 mpz_add_ui (*current_expand.count, *current_expand.count, 1);
1141 else
1142 {
1143 if (gfc_array_size (e, &result) == FAILURE)
1144 {
1145 gfc_free_expr (e);
1146 return FAILURE;
1147 }
1148
1149 mpz_add (*current_expand.count, *current_expand.count, result);
1150 mpz_clear (result);
1151 }
1152
1153 gfc_free_expr (e);
1154 return SUCCESS;
1155 }
1156
1157
1158 /* Work function that extracts a particular element from an array
1159 constructor, freeing the rest. */
1160
1161 static try
1162 extract_element (gfc_expr * e)
1163 {
1164
1165 if (e->rank != 0)
1166 { /* Something unextractable */
1167 gfc_free_expr (e);
1168 return FAILURE;
1169 }
1170
1171 if (current_expand.extract_count == current_expand.extract_n)
1172 current_expand.extracted = e;
1173 else
1174 gfc_free_expr (e);
1175
1176 current_expand.extract_count++;
1177 return SUCCESS;
1178 }
1179
1180
1181 /* Work function that constructs a new constructor out of the old one,
1182 stringing new elements together. */
1183
1184 static try
1185 expand (gfc_expr * e)
1186 {
1187
1188 if (current_expand.new_head == NULL)
1189 current_expand.new_head = current_expand.new_tail =
1190 gfc_get_constructor ();
1191 else
1192 {
1193 current_expand.new_tail->next = gfc_get_constructor ();
1194 current_expand.new_tail = current_expand.new_tail->next;
1195 }
1196
1197 current_expand.new_tail->where = e->where;
1198 current_expand.new_tail->expr = e;
1199
1200 mpz_set (current_expand.new_tail->n.offset, *current_expand.offset);
1201 current_expand.new_tail->n.component = current_expand.component;
1202 mpz_set (current_expand.new_tail->repeat, *current_expand.repeat);
1203 return SUCCESS;
1204 }
1205
1206
1207 /* Given an initialization expression that is a variable reference,
1208 substitute the current value of the iteration variable. */
1209
1210 void
1211 gfc_simplify_iterator_var (gfc_expr * e)
1212 {
1213 iterator_stack *p;
1214
1215 for (p = iter_stack; p; p = p->prev)
1216 if (e->symtree == p->variable)
1217 break;
1218
1219 if (p == NULL)
1220 return; /* Variable not found */
1221
1222 gfc_replace_expr (e, gfc_int_expr (0));
1223
1224 mpz_set (e->value.integer, p->value);
1225
1226 return;
1227 }
1228
1229
1230 /* Expand an expression with that is inside of a constructor,
1231 recursing into other constructors if present. */
1232
1233 static try
1234 expand_expr (gfc_expr * e)
1235 {
1236
1237 if (e->expr_type == EXPR_ARRAY)
1238 return expand_constructor (e->value.constructor);
1239
1240 e = gfc_copy_expr (e);
1241
1242 if (gfc_simplify_expr (e, 1) == FAILURE)
1243 {
1244 gfc_free_expr (e);
1245 return FAILURE;
1246 }
1247
1248 return current_expand.expand_work_function (e);
1249 }
1250
1251
1252 static try
1253 expand_iterator (gfc_constructor * c)
1254 {
1255 gfc_expr *start, *end, *step;
1256 iterator_stack frame;
1257 mpz_t trip;
1258 try t;
1259
1260 end = step = NULL;
1261
1262 t = FAILURE;
1263
1264 mpz_init (trip);
1265 mpz_init (frame.value);
1266
1267 start = gfc_copy_expr (c->iterator->start);
1268 if (gfc_simplify_expr (start, 1) == FAILURE)
1269 goto cleanup;
1270
1271 if (start->expr_type != EXPR_CONSTANT || start->ts.type != BT_INTEGER)
1272 goto cleanup;
1273
1274 end = gfc_copy_expr (c->iterator->end);
1275 if (gfc_simplify_expr (end, 1) == FAILURE)
1276 goto cleanup;
1277
1278 if (end->expr_type != EXPR_CONSTANT || end->ts.type != BT_INTEGER)
1279 goto cleanup;
1280
1281 step = gfc_copy_expr (c->iterator->step);
1282 if (gfc_simplify_expr (step, 1) == FAILURE)
1283 goto cleanup;
1284
1285 if (step->expr_type != EXPR_CONSTANT || step->ts.type != BT_INTEGER)
1286 goto cleanup;
1287
1288 if (mpz_sgn (step->value.integer) == 0)
1289 {
1290 gfc_error ("Iterator step at %L cannot be zero", &step->where);
1291 goto cleanup;
1292 }
1293
1294 /* Calculate the trip count of the loop. */
1295 mpz_sub (trip, end->value.integer, start->value.integer);
1296 mpz_add (trip, trip, step->value.integer);
1297 mpz_tdiv_q (trip, trip, step->value.integer);
1298
1299 mpz_set (frame.value, start->value.integer);
1300
1301 frame.prev = iter_stack;
1302 frame.variable = c->iterator->var->symtree;
1303 iter_stack = &frame;
1304
1305 while (mpz_sgn (trip) > 0)
1306 {
1307 if (expand_expr (c->expr) == FAILURE)
1308 goto cleanup;
1309
1310 mpz_add (frame.value, frame.value, step->value.integer);
1311 mpz_sub_ui (trip, trip, 1);
1312 }
1313
1314 t = SUCCESS;
1315
1316 cleanup:
1317 gfc_free_expr (start);
1318 gfc_free_expr (end);
1319 gfc_free_expr (step);
1320
1321 mpz_clear (trip);
1322 mpz_clear (frame.value);
1323
1324 iter_stack = frame.prev;
1325
1326 return t;
1327 }
1328
1329
1330 /* Expand a constructor into constant constructors without any
1331 iterators, calling the work function for each of the expanded
1332 expressions. The work function needs to either save or free the
1333 passed expression. */
1334
1335 static try
1336 expand_constructor (gfc_constructor * c)
1337 {
1338 gfc_expr *e;
1339
1340 for (; c; c = c->next)
1341 {
1342 if (c->iterator != NULL)
1343 {
1344 if (expand_iterator (c) == FAILURE)
1345 return FAILURE;
1346 continue;
1347 }
1348
1349 e = c->expr;
1350
1351 if (e->expr_type == EXPR_ARRAY)
1352 {
1353 if (expand_constructor (e->value.constructor) == FAILURE)
1354 return FAILURE;
1355
1356 continue;
1357 }
1358
1359 e = gfc_copy_expr (e);
1360 if (gfc_simplify_expr (e, 1) == FAILURE)
1361 {
1362 gfc_free_expr (e);
1363 return FAILURE;
1364 }
1365 current_expand.offset = &c->n.offset;
1366 current_expand.component = c->n.component;
1367 current_expand.repeat = &c->repeat;
1368 if (current_expand.expand_work_function (e) == FAILURE)
1369 return FAILURE;
1370 }
1371 return SUCCESS;
1372 }
1373
1374
1375 /* Top level subroutine for expanding constructors. We only expand
1376 constructor if they are small enough. */
1377
1378 try
1379 gfc_expand_constructor (gfc_expr * e)
1380 {
1381 expand_info expand_save;
1382 gfc_expr *f;
1383 try rc;
1384
1385 f = gfc_get_array_element (e, GFC_MAX_AC_EXPAND);
1386 if (f != NULL)
1387 {
1388 gfc_free_expr (f);
1389 return SUCCESS;
1390 }
1391
1392 expand_save = current_expand;
1393 current_expand.new_head = current_expand.new_tail = NULL;
1394
1395 iter_stack = NULL;
1396
1397 current_expand.expand_work_function = expand;
1398
1399 if (expand_constructor (e->value.constructor) == FAILURE)
1400 {
1401 gfc_free_constructor (current_expand.new_head);
1402 rc = FAILURE;
1403 goto done;
1404 }
1405
1406 gfc_free_constructor (e->value.constructor);
1407 e->value.constructor = current_expand.new_head;
1408
1409 rc = SUCCESS;
1410
1411 done:
1412 current_expand = expand_save;
1413
1414 return rc;
1415 }
1416
1417
1418 /* Work function for checking that an element of a constructor is a
1419 constant, after removal of any iteration variables. We return
1420 FAILURE if not so. */
1421
1422 static try
1423 constant_element (gfc_expr * e)
1424 {
1425 int rv;
1426
1427 rv = gfc_is_constant_expr (e);
1428 gfc_free_expr (e);
1429
1430 return rv ? SUCCESS : FAILURE;
1431 }
1432
1433
1434 /* Given an array constructor, determine if the constructor is
1435 constant or not by expanding it and making sure that all elements
1436 are constants. This is a bit of a hack since something like (/ (i,
1437 i=1,100000000) /) will take a while as* opposed to a more clever
1438 function that traverses the expression tree. FIXME. */
1439
1440 int
1441 gfc_constant_ac (gfc_expr * e)
1442 {
1443 expand_info expand_save;
1444 try rc;
1445
1446 iter_stack = NULL;
1447 expand_save = current_expand;
1448 current_expand.expand_work_function = constant_element;
1449
1450 rc = expand_constructor (e->value.constructor);
1451
1452 current_expand = expand_save;
1453 if (rc == FAILURE)
1454 return 0;
1455
1456 return 1;
1457 }
1458
1459
1460 /* Returns nonzero if an array constructor has been completely
1461 expanded (no iterators) and zero if iterators are present. */
1462
1463 int
1464 gfc_expanded_ac (gfc_expr * e)
1465 {
1466 gfc_constructor *p;
1467
1468 if (e->expr_type == EXPR_ARRAY)
1469 for (p = e->value.constructor; p; p = p->next)
1470 if (p->iterator != NULL || !gfc_expanded_ac (p->expr))
1471 return 0;
1472
1473 return 1;
1474 }
1475
1476
1477 /*************** Type resolution of array constructors ***************/
1478
1479 /* Recursive array list resolution function. All of the elements must
1480 be of the same type. */
1481
1482 static try
1483 resolve_array_list (gfc_constructor * p)
1484 {
1485 try t;
1486
1487 t = SUCCESS;
1488
1489 for (; p; p = p->next)
1490 {
1491 if (p->iterator != NULL
1492 && gfc_resolve_iterator (p->iterator) == FAILURE)
1493 t = FAILURE;
1494
1495 if (gfc_resolve_expr (p->expr) == FAILURE)
1496 t = FAILURE;
1497 }
1498
1499 return t;
1500 }
1501
1502
1503 /* Resolve all of the expressions in an array list.
1504 TODO: String lengths. */
1505
1506 try
1507 gfc_resolve_array_constructor (gfc_expr * expr)
1508 {
1509 try t;
1510
1511 t = resolve_array_list (expr->value.constructor);
1512 if (t == SUCCESS)
1513 t = gfc_check_constructor_type (expr);
1514
1515 return t;
1516 }
1517
1518
1519 /* Copy an iterator structure. */
1520
1521 static gfc_iterator *
1522 copy_iterator (gfc_iterator * src)
1523 {
1524 gfc_iterator *dest;
1525
1526 if (src == NULL)
1527 return NULL;
1528
1529 dest = gfc_get_iterator ();
1530
1531 dest->var = gfc_copy_expr (src->var);
1532 dest->start = gfc_copy_expr (src->start);
1533 dest->end = gfc_copy_expr (src->end);
1534 dest->step = gfc_copy_expr (src->step);
1535
1536 return dest;
1537 }
1538
1539
1540 /* Copy a constructor structure. */
1541
1542 gfc_constructor *
1543 gfc_copy_constructor (gfc_constructor * src)
1544 {
1545 gfc_constructor *dest;
1546 gfc_constructor *tail;
1547
1548 if (src == NULL)
1549 return NULL;
1550
1551 dest = tail = NULL;
1552 while (src)
1553 {
1554 if (dest == NULL)
1555 dest = tail = gfc_get_constructor ();
1556 else
1557 {
1558 tail->next = gfc_get_constructor ();
1559 tail = tail->next;
1560 }
1561 tail->where = src->where;
1562 tail->expr = gfc_copy_expr (src->expr);
1563 tail->iterator = copy_iterator (src->iterator);
1564 mpz_set (tail->n.offset, src->n.offset);
1565 tail->n.component = src->n.component;
1566 mpz_set (tail->repeat, src->repeat);
1567 src = src->next;
1568 }
1569
1570 return dest;
1571 }
1572
1573
1574 /* Given an array expression and an element number (starting at zero),
1575 return a pointer to the array element. NULL is returned if the
1576 size of the array has been exceeded. The expression node returned
1577 remains a part of the array and should not be freed. Access is not
1578 efficient at all, but this is another place where things do not
1579 have to be particularly fast. */
1580
1581 gfc_expr *
1582 gfc_get_array_element (gfc_expr * array, int element)
1583 {
1584 expand_info expand_save;
1585 gfc_expr *e;
1586 try rc;
1587
1588 expand_save = current_expand;
1589 current_expand.extract_n = element;
1590 current_expand.expand_work_function = extract_element;
1591 current_expand.extracted = NULL;
1592 current_expand.extract_count = 0;
1593
1594 iter_stack = NULL;
1595
1596 rc = expand_constructor (array->value.constructor);
1597 e = current_expand.extracted;
1598 current_expand = expand_save;
1599
1600 if (rc == FAILURE)
1601 return NULL;
1602
1603 return e;
1604 }
1605
1606
1607 /********* Subroutines for determining the size of an array *********/
1608
1609 /* These are needed just to accomodate RESHAPE(). There are no
1610 diagnostics here, we just return a negative number if something
1611 goes wrong. */
1612
1613
1614 /* Get the size of single dimension of an array specification. The
1615 array is guaranteed to be one dimensional. */
1616
1617 static try
1618 spec_dimen_size (gfc_array_spec * as, int dimen, mpz_t * result)
1619 {
1620
1621 if (as == NULL)
1622 return FAILURE;
1623
1624 if (dimen < 0 || dimen > as->rank - 1)
1625 gfc_internal_error ("spec_dimen_size(): Bad dimension");
1626
1627 if (as->type != AS_EXPLICIT
1628 || as->lower[dimen]->expr_type != EXPR_CONSTANT
1629 || as->upper[dimen]->expr_type != EXPR_CONSTANT)
1630 return FAILURE;
1631
1632 mpz_init (*result);
1633
1634 mpz_sub (*result, as->upper[dimen]->value.integer,
1635 as->lower[dimen]->value.integer);
1636
1637 mpz_add_ui (*result, *result, 1);
1638
1639 return SUCCESS;
1640 }
1641
1642
1643 try
1644 spec_size (gfc_array_spec * as, mpz_t * result)
1645 {
1646 mpz_t size;
1647 int d;
1648
1649 mpz_init_set_ui (*result, 1);
1650
1651 for (d = 0; d < as->rank; d++)
1652 {
1653 if (spec_dimen_size (as, d, &size) == FAILURE)
1654 {
1655 mpz_clear (*result);
1656 return FAILURE;
1657 }
1658
1659 mpz_mul (*result, *result, size);
1660 mpz_clear (size);
1661 }
1662
1663 return SUCCESS;
1664 }
1665
1666
1667 /* Get the number of elements in an array section. */
1668
1669 static try
1670 ref_dimen_size (gfc_array_ref * ar, int dimen, mpz_t * result)
1671 {
1672 mpz_t upper, lower, stride;
1673 try t;
1674
1675 if (dimen < 0 || ar == NULL || dimen > ar->dimen - 1)
1676 gfc_internal_error ("ref_dimen_size(): Bad dimension");
1677
1678 switch (ar->dimen_type[dimen])
1679 {
1680 case DIMEN_ELEMENT:
1681 mpz_init (*result);
1682 mpz_set_ui (*result, 1);
1683 t = SUCCESS;
1684 break;
1685
1686 case DIMEN_VECTOR:
1687 t = gfc_array_size (ar->start[dimen], result); /* Recurse! */
1688 break;
1689
1690 case DIMEN_RANGE:
1691 mpz_init (upper);
1692 mpz_init (lower);
1693 mpz_init (stride);
1694 t = FAILURE;
1695
1696 if (ar->start[dimen] == NULL)
1697 {
1698 if (ar->as->lower[dimen] == NULL
1699 || ar->as->lower[dimen]->expr_type != EXPR_CONSTANT)
1700 goto cleanup;
1701 mpz_set (lower, ar->as->lower[dimen]->value.integer);
1702 }
1703 else
1704 {
1705 if (ar->start[dimen]->expr_type != EXPR_CONSTANT)
1706 goto cleanup;
1707 mpz_set (lower, ar->start[dimen]->value.integer);
1708 }
1709
1710 if (ar->end[dimen] == NULL)
1711 {
1712 if (ar->as->upper[dimen] == NULL
1713 || ar->as->upper[dimen]->expr_type != EXPR_CONSTANT)
1714 goto cleanup;
1715 mpz_set (upper, ar->as->upper[dimen]->value.integer);
1716 }
1717 else
1718 {
1719 if (ar->end[dimen]->expr_type != EXPR_CONSTANT)
1720 goto cleanup;
1721 mpz_set (upper, ar->end[dimen]->value.integer);
1722 }
1723
1724 if (ar->stride[dimen] == NULL)
1725 mpz_set_ui (stride, 1);
1726 else
1727 {
1728 if (ar->stride[dimen]->expr_type != EXPR_CONSTANT)
1729 goto cleanup;
1730 mpz_set (stride, ar->stride[dimen]->value.integer);
1731 }
1732
1733 mpz_init (*result);
1734 mpz_sub (*result, upper, lower);
1735 mpz_add (*result, *result, stride);
1736 mpz_div (*result, *result, stride);
1737
1738 /* Zero stride caught earlier. */
1739 if (mpz_cmp_ui (*result, 0) < 0)
1740 mpz_set_ui (*result, 0);
1741 t = SUCCESS;
1742
1743 cleanup:
1744 mpz_clear (upper);
1745 mpz_clear (lower);
1746 mpz_clear (stride);
1747 return t;
1748
1749 default:
1750 gfc_internal_error ("ref_dimen_size(): Bad dimen_type");
1751 }
1752
1753 return t;
1754 }
1755
1756
1757 static try
1758 ref_size (gfc_array_ref * ar, mpz_t * result)
1759 {
1760 mpz_t size;
1761 int d;
1762
1763 mpz_init_set_ui (*result, 1);
1764
1765 for (d = 0; d < ar->dimen; d++)
1766 {
1767 if (ref_dimen_size (ar, d, &size) == FAILURE)
1768 {
1769 mpz_clear (*result);
1770 return FAILURE;
1771 }
1772
1773 mpz_mul (*result, *result, size);
1774 mpz_clear (size);
1775 }
1776
1777 return SUCCESS;
1778 }
1779
1780
1781 /* Given an array expression and a dimension, figure out how many
1782 elements it has along that dimension. Returns SUCCESS if we were
1783 able to return a result in the 'result' variable, FAILURE
1784 otherwise. */
1785
1786 try
1787 gfc_array_dimen_size (gfc_expr * array, int dimen, mpz_t * result)
1788 {
1789 gfc_ref *ref;
1790 int i;
1791
1792 if (dimen < 0 || array == NULL || dimen > array->rank - 1)
1793 gfc_internal_error ("gfc_array_dimen_size(): Bad dimension");
1794
1795 switch (array->expr_type)
1796 {
1797 case EXPR_VARIABLE:
1798 case EXPR_FUNCTION:
1799 for (ref = array->ref; ref; ref = ref->next)
1800 {
1801 if (ref->type != REF_ARRAY)
1802 continue;
1803
1804 if (ref->u.ar.type == AR_FULL)
1805 return spec_dimen_size (ref->u.ar.as, dimen, result);
1806
1807 if (ref->u.ar.type == AR_SECTION)
1808 {
1809 for (i = 0; dimen >= 0; i++)
1810 if (ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1811 dimen--;
1812
1813 return ref_dimen_size (&ref->u.ar, i - 1, result);
1814 }
1815 }
1816
1817 if (spec_dimen_size (array->symtree->n.sym->as, dimen, result) == FAILURE)
1818 return FAILURE;
1819
1820 break;
1821
1822 case EXPR_ARRAY:
1823 if (array->shape == NULL) {
1824 /* Expressions with rank > 1 should have "shape" properly set */
1825 if ( array->rank != 1 )
1826 gfc_internal_error ("gfc_array_dimen_size(): Bad EXPR_ARRAY expr");
1827 return gfc_array_size(array, result);
1828 }
1829
1830 /* Fall through */
1831 default:
1832 if (array->shape == NULL)
1833 return FAILURE;
1834
1835 mpz_init_set (*result, array->shape[dimen]);
1836
1837 break;
1838 }
1839
1840 return SUCCESS;
1841 }
1842
1843
1844 /* Given an array expression, figure out how many elements are in the
1845 array. Returns SUCCESS if this is possible, and sets the 'result'
1846 variable. Otherwise returns FAILURE. */
1847
1848 try
1849 gfc_array_size (gfc_expr * array, mpz_t * result)
1850 {
1851 expand_info expand_save;
1852 gfc_ref *ref;
1853 int i, flag;
1854 try t;
1855
1856 switch (array->expr_type)
1857 {
1858 case EXPR_ARRAY:
1859 flag = gfc_suppress_error;
1860 gfc_suppress_error = 1;
1861
1862 expand_save = current_expand;
1863
1864 current_expand.count = result;
1865 mpz_init_set_ui (*result, 0);
1866
1867 current_expand.expand_work_function = count_elements;
1868 iter_stack = NULL;
1869
1870 t = expand_constructor (array->value.constructor);
1871 gfc_suppress_error = flag;
1872
1873 if (t == FAILURE)
1874 mpz_clear (*result);
1875 current_expand = expand_save;
1876 return t;
1877
1878 case EXPR_VARIABLE:
1879 for (ref = array->ref; ref; ref = ref->next)
1880 {
1881 if (ref->type != REF_ARRAY)
1882 continue;
1883
1884 if (ref->u.ar.type == AR_FULL)
1885 return spec_size (ref->u.ar.as, result);
1886
1887 if (ref->u.ar.type == AR_SECTION)
1888 return ref_size (&ref->u.ar, result);
1889 }
1890
1891 return spec_size (array->symtree->n.sym->as, result);
1892
1893
1894 default:
1895 if (array->rank == 0 || array->shape == NULL)
1896 return FAILURE;
1897
1898 mpz_init_set_ui (*result, 1);
1899
1900 for (i = 0; i < array->rank; i++)
1901 mpz_mul (*result, *result, array->shape[i]);
1902
1903 break;
1904 }
1905
1906 return SUCCESS;
1907 }
1908
1909
1910 /* Given an array reference, return the shape of the reference in an
1911 array of mpz_t integers. */
1912
1913 try
1914 gfc_array_ref_shape (gfc_array_ref * ar, mpz_t * shape)
1915 {
1916 int d;
1917 int i;
1918
1919 d = 0;
1920
1921 switch (ar->type)
1922 {
1923 case AR_FULL:
1924 for (; d < ar->as->rank; d++)
1925 if (spec_dimen_size (ar->as, d, &shape[d]) == FAILURE)
1926 goto cleanup;
1927
1928 return SUCCESS;
1929
1930 case AR_SECTION:
1931 for (i = 0; i < ar->dimen; i++)
1932 {
1933 if (ar->dimen_type[i] != DIMEN_ELEMENT)
1934 {
1935 if (ref_dimen_size (ar, i, &shape[d]) == FAILURE)
1936 goto cleanup;
1937 d++;
1938 }
1939 }
1940
1941 return SUCCESS;
1942
1943 default:
1944 break;
1945 }
1946
1947 cleanup:
1948 for (d--; d >= 0; d--)
1949 mpz_clear (shape[d]);
1950
1951 return FAILURE;
1952 }
1953
1954
1955 /* Given an array expression, find the array reference structure that
1956 characterizes the reference. */
1957
1958 gfc_array_ref *
1959 gfc_find_array_ref (gfc_expr * e)
1960 {
1961 gfc_ref *ref;
1962
1963 for (ref = e->ref; ref; ref = ref->next)
1964 if (ref->type == REF_ARRAY
1965 && (ref->u.ar.type == AR_FULL
1966 || ref->u.ar.type == AR_SECTION))
1967 break;
1968
1969 if (ref == NULL)
1970 gfc_internal_error ("gfc_find_array_ref(): No ref found");
1971
1972 return &ref->u.ar;
1973 }