]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/array.c
unicode-muncher.pl: Updated to version 2.1 from GNU classpath.
[thirdparty/gcc.git] / gcc / fortran / array.c
CommitLineData
6de9cd9a 1/* Array things
da4f9e3b 2 Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Andy Vaught
4
9fc4d79b 5This file is part of GCC.
6de9cd9a 6
9fc4d79b
TS
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
6de9cd9a 11
9fc4d79b
TS
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
6de9cd9a
DN
16
17You should have received a copy of the GNU General Public License
9fc4d79b
TS
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
6de9cd9a
DN
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
40gfc_array_ref *
41gfc_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
72static match
73match_subscript (gfc_array_ref * ar, int init)
74{
75 match m;
76 int i;
77
78 i = ar->dimen;
79
63645982 80 ar->c_where[i] = gfc_current_locus;
6de9cd9a
DN
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. */
108end_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
139match
140gfc_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
63645982 146 ar->where = gfc_current_locus;
6de9cd9a
DN
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
177error:
178 return MATCH_ERROR;
179
180matched:
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
192void
193gfc_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
213static try
214resolve_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
238try
239gfc_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
282static array_type
283match_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
331match
332gfc_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
444cleanup:
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
455try
456gfc_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
473gfc_array_spec *
474gfc_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
498static int
499compare_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
517int
518gfc_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
556gfc_expr *
557gfc_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
576void
577gfc_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
603void
604gfc_insert_constructor (gfc_expr * base, gfc_constructor * c1)
605{
606 gfc_constructor *c, *pre;
607 expr_t type;
da4f9e3b 608 int t;
6de9cd9a
DN
609
610 type = base->expr_type;
611
612 if (base->value.constructor == NULL)
613 base->value.constructor = c1;
614 else
615 {
616 c = pre = base->value.constructor;
617 while (c)
618 {
619 if (type == EXPR_ARRAY)
620 {
da4f9e3b
TS
621 t = mpz_cmp (c->n.offset, c1->n.offset);
622 if (t < 0)
6de9cd9a
DN
623 {
624 pre = c;
625 c = c->next;
626 }
da4f9e3b 627 else if (t == 0)
6de9cd9a
DN
628 {
629 gfc_error ("duplicated initializer");
630 break;
631 }
632 else
633 break;
634 }
635 else
636 {
637 pre = c;
638 c = c->next;
639 }
640 }
641
642 if (pre != c)
643 {
644 pre->next = c1;
645 c1->next = c;
646 }
647 else
648 {
649 c1->next = c;
650 base->value.constructor = c1;
651 }
652 }
653}
654
655
656/* Get a new constructor. */
657
658gfc_constructor *
659gfc_get_constructor (void)
660{
661 gfc_constructor *c;
662
663 c = gfc_getmem (sizeof(gfc_constructor));
664 c->expr = NULL;
665 c->iterator = NULL;
666 c->next = NULL;
667 mpz_init_set_si (c->n.offset, 0);
668 mpz_init_set_si (c->repeat, 0);
669 return c;
670}
671
672
673/* Free chains of gfc_constructor structures. */
674
675void
676gfc_free_constructor (gfc_constructor * p)
677{
678 gfc_constructor *next;
679
680 if (p == NULL)
681 return;
682
683 for (; p; p = next)
684 {
685 next = p->next;
686
687 if (p->expr)
688 gfc_free_expr (p->expr);
689 if (p->iterator != NULL)
690 gfc_free_iterator (p->iterator, 1);
691 mpz_clear (p->n.offset);
692 mpz_clear (p->repeat);
693 gfc_free (p);
694 }
695}
696
697
698/* Given an expression node that might be an array constructor and a
699 symbol, make sure that no iterators in this or child constructors
700 use the symbol as an implied-DO iterator. Returns nonzero if a
701 duplicate was found. */
702
703static int
704check_duplicate_iterator (gfc_constructor * c, gfc_symbol * master)
705{
706 gfc_expr *e;
707
708 for (; c; c = c->next)
709 {
710 e = c->expr;
711
712 if (e->expr_type == EXPR_ARRAY
713 && check_duplicate_iterator (e->value.constructor, master))
714 return 1;
715
716 if (c->iterator == NULL)
717 continue;
718
719 if (c->iterator->var->symtree->n.sym == master)
720 {
721 gfc_error
722 ("DO-iterator '%s' at %L is inside iterator of the same name",
723 master->name, &c->where);
724
725 return 1;
726 }
727 }
728
729 return 0;
730}
731
732
733/* Forward declaration because these functions are mutually recursive. */
734static match match_array_cons_element (gfc_constructor **);
735
736/* Match a list of array elements. */
737
738static match
739match_array_list (gfc_constructor ** result)
740{
741 gfc_constructor *p, *head, *tail, *new;
742 gfc_iterator iter;
743 locus old_loc;
744 gfc_expr *e;
745 match m;
746 int n;
747
63645982 748 old_loc = gfc_current_locus;
6de9cd9a
DN
749
750 if (gfc_match_char ('(') == MATCH_NO)
751 return MATCH_NO;
752
753 memset (&iter, '\0', sizeof (gfc_iterator));
754 head = NULL;
755
756 m = match_array_cons_element (&head);
757 if (m != MATCH_YES)
758 goto cleanup;
759
760 tail = head;
761
762 if (gfc_match_char (',') != MATCH_YES)
763 {
764 m = MATCH_NO;
765 goto cleanup;
766 }
767
768 for (n = 1;; n++)
769 {
770 m = gfc_match_iterator (&iter, 0);
771 if (m == MATCH_YES)
772 break;
773 if (m == MATCH_ERROR)
774 goto cleanup;
775
776 m = match_array_cons_element (&new);
777 if (m == MATCH_ERROR)
778 goto cleanup;
779 if (m == MATCH_NO)
780 {
781 if (n > 2)
782 goto syntax;
783 m = MATCH_NO;
784 goto cleanup; /* Could be a complex constant */
785 }
786
787 tail->next = new;
788 tail = new;
789
790 if (gfc_match_char (',') != MATCH_YES)
791 {
792 if (n > 2)
793 goto syntax;
794 m = MATCH_NO;
795 goto cleanup;
796 }
797 }
798
799 if (gfc_match_char (')') != MATCH_YES)
800 goto syntax;
801
802 if (check_duplicate_iterator (head, iter.var->symtree->n.sym))
803 {
804 m = MATCH_ERROR;
805 goto cleanup;
806 }
807
808 e = gfc_get_expr ();
809 e->expr_type = EXPR_ARRAY;
810 e->where = old_loc;
811 e->value.constructor = head;
812
813 p = gfc_get_constructor ();
63645982 814 p->where = gfc_current_locus;
6de9cd9a
DN
815 p->iterator = gfc_get_iterator ();
816 *p->iterator = iter;
817
818 p->expr = e;
819 *result = p;
820
821 return MATCH_YES;
822
823syntax:
824 gfc_error ("Syntax error in array constructor at %C");
825 m = MATCH_ERROR;
826
827cleanup:
828 gfc_free_constructor (head);
829 gfc_free_iterator (&iter, 0);
63645982 830 gfc_current_locus = old_loc;
6de9cd9a
DN
831 return m;
832}
833
834
835/* Match a single element of an array constructor, which can be a
836 single expression or a list of elements. */
837
838static match
839match_array_cons_element (gfc_constructor ** result)
840{
841 gfc_constructor *p;
842 gfc_expr *expr;
843 match m;
844
845 m = match_array_list (result);
846 if (m != MATCH_NO)
847 return m;
848
849 m = gfc_match_expr (&expr);
850 if (m != MATCH_YES)
851 return m;
852
853 p = gfc_get_constructor ();
63645982 854 p->where = gfc_current_locus;
6de9cd9a
DN
855 p->expr = expr;
856
857 *result = p;
858 return MATCH_YES;
859}
860
861
862/* Match an array constructor. */
863
864match
865gfc_match_array_constructor (gfc_expr ** result)
866{
867 gfc_constructor *head, *tail, *new;
868 gfc_expr *expr;
869 locus where;
870 match m;
871
872 if (gfc_match (" (/") == MATCH_NO)
873 return MATCH_NO;
874
63645982 875 where = gfc_current_locus;
6de9cd9a
DN
876 head = tail = NULL;
877
878 if (gfc_match (" /)") == MATCH_YES)
879 goto empty; /* Special case */
880
881 for (;;)
882 {
883 m = match_array_cons_element (&new);
884 if (m == MATCH_ERROR)
885 goto cleanup;
886 if (m == MATCH_NO)
887 goto syntax;
888
889 if (head == NULL)
890 head = new;
891 else
892 tail->next = new;
893
894 tail = new;
895
896 if (gfc_match_char (',') == MATCH_NO)
897 break;
898 }
899
900 if (gfc_match (" /)") == MATCH_NO)
901 goto syntax;
902
903empty:
904 expr = gfc_get_expr ();
905
906 expr->expr_type = EXPR_ARRAY;
907
908 expr->value.constructor = head;
909 /* Size must be calculated at resolution time. */
910
911 expr->where = where;
912 expr->rank = 1;
913
914 *result = expr;
915 return MATCH_YES;
916
917syntax:
918 gfc_error ("Syntax error in array constructor at %C");
919
920cleanup:
921 gfc_free_constructor (head);
922 return MATCH_ERROR;
923}
924
925
926
927/************** Check array constructors for correctness **************/
928
929/* Given an expression, compare it's type with the type of the current
930 constructor. Returns nonzero if an error was issued. The
931 cons_state variable keeps track of whether the type of the
932 constructor being read or resolved is known to be good, bad or just
933 starting out. */
934
935static gfc_typespec constructor_ts;
936static enum
937{ CONS_START, CONS_GOOD, CONS_BAD }
938cons_state;
939
940static int
941check_element_type (gfc_expr * expr)
942{
943
944 if (cons_state == CONS_BAD)
945 return 0; /* Supress further errors */
946
947 if (cons_state == CONS_START)
948 {
949 if (expr->ts.type == BT_UNKNOWN)
950 cons_state = CONS_BAD;
951 else
952 {
953 cons_state = CONS_GOOD;
954 constructor_ts = expr->ts;
955 }
956
957 return 0;
958 }
959
960 if (gfc_compare_types (&constructor_ts, &expr->ts))
961 return 0;
962
963 gfc_error ("Element in %s array constructor at %L is %s",
964 gfc_typename (&constructor_ts), &expr->where,
965 gfc_typename (&expr->ts));
966
967 cons_state = CONS_BAD;
968 return 1;
969}
970
971
972/* Recursive work function for gfc_check_constructor_type(). */
973
974static try
975check_constructor_type (gfc_constructor * c)
976{
977 gfc_expr *e;
978
979 for (; c; c = c->next)
980 {
981 e = c->expr;
982
983 if (e->expr_type == EXPR_ARRAY)
984 {
985 if (check_constructor_type (e->value.constructor) == FAILURE)
986 return FAILURE;
987
988 continue;
989 }
990
991 if (check_element_type (e))
992 return FAILURE;
993 }
994
995 return SUCCESS;
996}
997
998
999/* Check that all elements of an array constructor are the same type.
1000 On FAILURE, an error has been generated. */
1001
1002try
1003gfc_check_constructor_type (gfc_expr * e)
1004{
1005 try t;
1006
1007 cons_state = CONS_START;
1008 gfc_clear_ts (&constructor_ts);
1009
1010 t = check_constructor_type (e->value.constructor);
1011 if (t == SUCCESS && e->ts.type == BT_UNKNOWN)
1012 e->ts = constructor_ts;
1013
1014 return t;
1015}
1016
1017
1018
1019typedef struct cons_stack
1020{
1021 gfc_iterator *iterator;
1022 struct cons_stack *previous;
1023}
1024cons_stack;
1025
1026static cons_stack *base;
1027
1028static try check_constructor (gfc_constructor *, try (*)(gfc_expr *));
1029
1030/* Check an EXPR_VARIABLE expression in a constructor to make sure
1031 that that variable is an iteration variables. */
1032
1033try
1034gfc_check_iter_variable (gfc_expr * expr)
1035{
1036
1037 gfc_symbol *sym;
1038 cons_stack *c;
1039
1040 sym = expr->symtree->n.sym;
1041
1042 for (c = base; c; c = c->previous)
1043 if (sym == c->iterator->var->symtree->n.sym)
1044 return SUCCESS;
1045
1046 return FAILURE;
1047}
1048
1049
1050/* Recursive work function for gfc_check_constructor(). This amounts
1051 to calling the check function for each expression in the
1052 constructor, giving variables with the names of iterators a pass. */
1053
1054static try
1055check_constructor (gfc_constructor * c, try (*check_function) (gfc_expr *))
1056{
1057 cons_stack element;
1058 gfc_expr *e;
1059 try t;
1060
1061 for (; c; c = c->next)
1062 {
1063 e = c->expr;
1064
1065 if (e->expr_type != EXPR_ARRAY)
1066 {
1067 if ((*check_function) (e) == FAILURE)
1068 return FAILURE;
1069 continue;
1070 }
1071
1072 element.previous = base;
1073 element.iterator = c->iterator;
1074
1075 base = &element;
1076 t = check_constructor (e->value.constructor, check_function);
1077 base = element.previous;
1078
1079 if (t == FAILURE)
1080 return FAILURE;
1081 }
1082
1083 /* Nothing went wrong, so all OK. */
1084 return SUCCESS;
1085}
1086
1087
1088/* Checks a constructor to see if it is a particular kind of
1089 expression -- specification, restricted, or initialization as
1090 determined by the check_function. */
1091
1092try
1093gfc_check_constructor (gfc_expr * expr, try (*check_function) (gfc_expr *))
1094{
1095 cons_stack *base_save;
1096 try t;
1097
1098 base_save = base;
1099 base = NULL;
1100
1101 t = check_constructor (expr->value.constructor, check_function);
1102 base = base_save;
1103
1104 return t;
1105}
1106
1107
1108
1109/**************** Simplification of array constructors ****************/
1110
1111iterator_stack *iter_stack;
1112
1113typedef struct
1114{
1115 gfc_constructor *new_head, *new_tail;
1116 int extract_count, extract_n;
1117 gfc_expr *extracted;
1118 mpz_t *count;
1119
1120 mpz_t *offset;
1121 gfc_component *component;
1122 mpz_t *repeat;
1123
1124 try (*expand_work_function) (gfc_expr *);
1125}
1126expand_info;
1127
1128static expand_info current_expand;
1129
1130static try expand_constructor (gfc_constructor *);
1131
1132
1133/* Work function that counts the number of elements present in a
1134 constructor. */
1135
1136static try
1137count_elements (gfc_expr * e)
1138{
1139 mpz_t result;
1140
1141 if (e->rank == 0)
1142 mpz_add_ui (*current_expand.count, *current_expand.count, 1);
1143 else
1144 {
1145 if (gfc_array_size (e, &result) == FAILURE)
1146 {
1147 gfc_free_expr (e);
1148 return FAILURE;
1149 }
1150
1151 mpz_add (*current_expand.count, *current_expand.count, result);
1152 mpz_clear (result);
1153 }
1154
1155 gfc_free_expr (e);
1156 return SUCCESS;
1157}
1158
1159
1160/* Work function that extracts a particular element from an array
1161 constructor, freeing the rest. */
1162
1163static try
1164extract_element (gfc_expr * e)
1165{
1166
1167 if (e->rank != 0)
1168 { /* Something unextractable */
1169 gfc_free_expr (e);
1170 return FAILURE;
1171 }
1172
1173 if (current_expand.extract_count == current_expand.extract_n)
1174 current_expand.extracted = e;
1175 else
1176 gfc_free_expr (e);
1177
1178 current_expand.extract_count++;
1179 return SUCCESS;
1180}
1181
1182
1183/* Work function that constructs a new constructor out of the old one,
1184 stringing new elements together. */
1185
1186static try
1187expand (gfc_expr * e)
1188{
1189
1190 if (current_expand.new_head == NULL)
1191 current_expand.new_head = current_expand.new_tail =
1192 gfc_get_constructor ();
1193 else
1194 {
1195 current_expand.new_tail->next = gfc_get_constructor ();
1196 current_expand.new_tail = current_expand.new_tail->next;
1197 }
1198
1199 current_expand.new_tail->where = e->where;
1200 current_expand.new_tail->expr = e;
1201
1202 mpz_set (current_expand.new_tail->n.offset, *current_expand.offset);
1203 current_expand.new_tail->n.component = current_expand.component;
1204 mpz_set (current_expand.new_tail->repeat, *current_expand.repeat);
1205 return SUCCESS;
1206}
1207
1208
1209/* Given an initialization expression that is a variable reference,
1210 substitute the current value of the iteration variable. */
1211
1212void
1213gfc_simplify_iterator_var (gfc_expr * e)
1214{
1215 iterator_stack *p;
1216
1217 for (p = iter_stack; p; p = p->prev)
1218 if (e->symtree == p->variable)
1219 break;
1220
1221 if (p == NULL)
1222 return; /* Variable not found */
1223
1224 gfc_replace_expr (e, gfc_int_expr (0));
1225
1226 mpz_set (e->value.integer, p->value);
1227
1228 return;
1229}
1230
1231
1232/* Expand an expression with that is inside of a constructor,
1233 recursing into other constructors if present. */
1234
1235static try
1236expand_expr (gfc_expr * e)
1237{
1238
1239 if (e->expr_type == EXPR_ARRAY)
1240 return expand_constructor (e->value.constructor);
1241
1242 e = gfc_copy_expr (e);
1243
1244 if (gfc_simplify_expr (e, 1) == FAILURE)
1245 {
1246 gfc_free_expr (e);
1247 return FAILURE;
1248 }
1249
1250 return current_expand.expand_work_function (e);
1251}
1252
1253
1254static try
1255expand_iterator (gfc_constructor * c)
1256{
1257 gfc_expr *start, *end, *step;
1258 iterator_stack frame;
1259 mpz_t trip;
1260 try t;
1261
1262 end = step = NULL;
1263
1264 t = FAILURE;
1265
1266 mpz_init (trip);
1267 mpz_init (frame.value);
1268
1269 start = gfc_copy_expr (c->iterator->start);
1270 if (gfc_simplify_expr (start, 1) == FAILURE)
1271 goto cleanup;
1272
1273 if (start->expr_type != EXPR_CONSTANT || start->ts.type != BT_INTEGER)
1274 goto cleanup;
1275
1276 end = gfc_copy_expr (c->iterator->end);
1277 if (gfc_simplify_expr (end, 1) == FAILURE)
1278 goto cleanup;
1279
1280 if (end->expr_type != EXPR_CONSTANT || end->ts.type != BT_INTEGER)
1281 goto cleanup;
1282
1283 step = gfc_copy_expr (c->iterator->step);
1284 if (gfc_simplify_expr (step, 1) == FAILURE)
1285 goto cleanup;
1286
1287 if (step->expr_type != EXPR_CONSTANT || step->ts.type != BT_INTEGER)
1288 goto cleanup;
1289
1290 if (mpz_sgn (step->value.integer) == 0)
1291 {
1292 gfc_error ("Iterator step at %L cannot be zero", &step->where);
1293 goto cleanup;
1294 }
1295
1296 /* Calculate the trip count of the loop. */
1297 mpz_sub (trip, end->value.integer, start->value.integer);
1298 mpz_add (trip, trip, step->value.integer);
1299 mpz_tdiv_q (trip, trip, step->value.integer);
1300
1301 mpz_set (frame.value, start->value.integer);
1302
1303 frame.prev = iter_stack;
1304 frame.variable = c->iterator->var->symtree;
1305 iter_stack = &frame;
1306
1307 while (mpz_sgn (trip) > 0)
1308 {
1309 if (expand_expr (c->expr) == FAILURE)
1310 goto cleanup;
1311
1312 mpz_add (frame.value, frame.value, step->value.integer);
1313 mpz_sub_ui (trip, trip, 1);
1314 }
1315
1316 t = SUCCESS;
1317
1318cleanup:
1319 gfc_free_expr (start);
1320 gfc_free_expr (end);
1321 gfc_free_expr (step);
1322
1323 mpz_clear (trip);
1324 mpz_clear (frame.value);
1325
1326 iter_stack = frame.prev;
1327
1328 return t;
1329}
1330
1331
1332/* Expand a constructor into constant constructors without any
1333 iterators, calling the work function for each of the expanded
1334 expressions. The work function needs to either save or free the
1335 passed expression. */
1336
1337static try
1338expand_constructor (gfc_constructor * c)
1339{
1340 gfc_expr *e;
1341
1342 for (; c; c = c->next)
1343 {
1344 if (c->iterator != NULL)
1345 {
1346 if (expand_iterator (c) == FAILURE)
1347 return FAILURE;
1348 continue;
1349 }
1350
1351 e = c->expr;
1352
1353 if (e->expr_type == EXPR_ARRAY)
1354 {
1355 if (expand_constructor (e->value.constructor) == FAILURE)
1356 return FAILURE;
1357
1358 continue;
1359 }
1360
1361 e = gfc_copy_expr (e);
1362 if (gfc_simplify_expr (e, 1) == FAILURE)
1363 {
1364 gfc_free_expr (e);
1365 return FAILURE;
1366 }
1367 current_expand.offset = &c->n.offset;
1368 current_expand.component = c->n.component;
1369 current_expand.repeat = &c->repeat;
1370 if (current_expand.expand_work_function (e) == FAILURE)
1371 return FAILURE;
1372 }
1373 return SUCCESS;
1374}
1375
1376
1377/* Top level subroutine for expanding constructors. We only expand
1378 constructor if they are small enough. */
1379
1380try
1381gfc_expand_constructor (gfc_expr * e)
1382{
1383 expand_info expand_save;
1384 gfc_expr *f;
1385 try rc;
1386
1387 f = gfc_get_array_element (e, GFC_MAX_AC_EXPAND);
1388 if (f != NULL)
1389 {
1390 gfc_free_expr (f);
1391 return SUCCESS;
1392 }
1393
1394 expand_save = current_expand;
1395 current_expand.new_head = current_expand.new_tail = NULL;
1396
1397 iter_stack = NULL;
1398
1399 current_expand.expand_work_function = expand;
1400
1401 if (expand_constructor (e->value.constructor) == FAILURE)
1402 {
1403 gfc_free_constructor (current_expand.new_head);
1404 rc = FAILURE;
1405 goto done;
1406 }
1407
1408 gfc_free_constructor (e->value.constructor);
1409 e->value.constructor = current_expand.new_head;
1410
1411 rc = SUCCESS;
1412
1413done:
1414 current_expand = expand_save;
1415
1416 return rc;
1417}
1418
1419
1420/* Work function for checking that an element of a constructor is a
1421 constant, after removal of any iteration variables. We return
1422 FAILURE if not so. */
1423
1424static try
1425constant_element (gfc_expr * e)
1426{
1427 int rv;
1428
1429 rv = gfc_is_constant_expr (e);
1430 gfc_free_expr (e);
1431
1432 return rv ? SUCCESS : FAILURE;
1433}
1434
1435
1436/* Given an array constructor, determine if the constructor is
1437 constant or not by expanding it and making sure that all elements
1438 are constants. This is a bit of a hack since something like (/ (i,
1439 i=1,100000000) /) will take a while as* opposed to a more clever
1440 function that traverses the expression tree. FIXME. */
1441
1442int
1443gfc_constant_ac (gfc_expr * e)
1444{
1445 expand_info expand_save;
1446 try rc;
1447
1448 iter_stack = NULL;
1449 expand_save = current_expand;
1450 current_expand.expand_work_function = constant_element;
1451
1452 rc = expand_constructor (e->value.constructor);
1453
1454 current_expand = expand_save;
1455 if (rc == FAILURE)
1456 return 0;
1457
1458 return 1;
1459}
1460
1461
1462/* Returns nonzero if an array constructor has been completely
1463 expanded (no iterators) and zero if iterators are present. */
1464
1465int
1466gfc_expanded_ac (gfc_expr * e)
1467{
1468 gfc_constructor *p;
1469
1470 if (e->expr_type == EXPR_ARRAY)
1471 for (p = e->value.constructor; p; p = p->next)
1472 if (p->iterator != NULL || !gfc_expanded_ac (p->expr))
1473 return 0;
1474
1475 return 1;
1476}
1477
1478
1479/*************** Type resolution of array constructors ***************/
1480
1481/* Recursive array list resolution function. All of the elements must
1482 be of the same type. */
1483
1484static try
1485resolve_array_list (gfc_constructor * p)
1486{
1487 try t;
1488
1489 t = SUCCESS;
1490
1491 for (; p; p = p->next)
1492 {
1493 if (p->iterator != NULL
1494 && gfc_resolve_iterator (p->iterator) == FAILURE)
1495 t = FAILURE;
1496
1497 if (gfc_resolve_expr (p->expr) == FAILURE)
1498 t = FAILURE;
1499 }
1500
1501 return t;
1502}
1503
1504
1505/* Resolve all of the expressions in an array list.
1506 TODO: String lengths. */
1507
1508try
1509gfc_resolve_array_constructor (gfc_expr * expr)
1510{
1511 try t;
1512
1513 t = resolve_array_list (expr->value.constructor);
1514 if (t == SUCCESS)
1515 t = gfc_check_constructor_type (expr);
1516
1517 return t;
1518}
1519
1520
1521/* Copy an iterator structure. */
1522
1523static gfc_iterator *
1524copy_iterator (gfc_iterator * src)
1525{
1526 gfc_iterator *dest;
1527
1528 if (src == NULL)
1529 return NULL;
1530
1531 dest = gfc_get_iterator ();
1532
1533 dest->var = gfc_copy_expr (src->var);
1534 dest->start = gfc_copy_expr (src->start);
1535 dest->end = gfc_copy_expr (src->end);
1536 dest->step = gfc_copy_expr (src->step);
1537
1538 return dest;
1539}
1540
1541
1542/* Copy a constructor structure. */
1543
1544gfc_constructor *
1545gfc_copy_constructor (gfc_constructor * src)
1546{
1547 gfc_constructor *dest;
1548 gfc_constructor *tail;
1549
1550 if (src == NULL)
1551 return NULL;
1552
1553 dest = tail = NULL;
1554 while (src)
1555 {
1556 if (dest == NULL)
1557 dest = tail = gfc_get_constructor ();
1558 else
1559 {
1560 tail->next = gfc_get_constructor ();
1561 tail = tail->next;
1562 }
1563 tail->where = src->where;
1564 tail->expr = gfc_copy_expr (src->expr);
1565 tail->iterator = copy_iterator (src->iterator);
1566 mpz_set (tail->n.offset, src->n.offset);
1567 tail->n.component = src->n.component;
1568 mpz_set (tail->repeat, src->repeat);
1569 src = src->next;
1570 }
1571
1572 return dest;
1573}
1574
1575
1576/* Given an array expression and an element number (starting at zero),
1577 return a pointer to the array element. NULL is returned if the
1578 size of the array has been exceeded. The expression node returned
1579 remains a part of the array and should not be freed. Access is not
1580 efficient at all, but this is another place where things do not
1581 have to be particularly fast. */
1582
1583gfc_expr *
1584gfc_get_array_element (gfc_expr * array, int element)
1585{
1586 expand_info expand_save;
1587 gfc_expr *e;
1588 try rc;
1589
1590 expand_save = current_expand;
1591 current_expand.extract_n = element;
1592 current_expand.expand_work_function = extract_element;
1593 current_expand.extracted = NULL;
1594 current_expand.extract_count = 0;
1595
1596 iter_stack = NULL;
1597
1598 rc = expand_constructor (array->value.constructor);
1599 e = current_expand.extracted;
1600 current_expand = expand_save;
1601
1602 if (rc == FAILURE)
1603 return NULL;
1604
1605 return e;
1606}
1607
1608
1609/********* Subroutines for determining the size of an array *********/
1610
1611/* These are needed just to accomodate RESHAPE(). There are no
1612 diagnostics here, we just return a negative number if something
1613 goes wrong. */
1614
1615
1616/* Get the size of single dimension of an array specification. The
1617 array is guaranteed to be one dimensional. */
1618
1619static try
1620spec_dimen_size (gfc_array_spec * as, int dimen, mpz_t * result)
1621{
1622
1623 if (as == NULL)
1624 return FAILURE;
1625
1626 if (dimen < 0 || dimen > as->rank - 1)
1627 gfc_internal_error ("spec_dimen_size(): Bad dimension");
1628
1629 if (as->type != AS_EXPLICIT
1630 || as->lower[dimen]->expr_type != EXPR_CONSTANT
1631 || as->upper[dimen]->expr_type != EXPR_CONSTANT)
1632 return FAILURE;
1633
1634 mpz_init (*result);
1635
1636 mpz_sub (*result, as->upper[dimen]->value.integer,
1637 as->lower[dimen]->value.integer);
1638
1639 mpz_add_ui (*result, *result, 1);
1640
1641 return SUCCESS;
1642}
1643
1644
1645try
1646spec_size (gfc_array_spec * as, mpz_t * result)
1647{
1648 mpz_t size;
1649 int d;
1650
1651 mpz_init_set_ui (*result, 1);
1652
1653 for (d = 0; d < as->rank; d++)
1654 {
1655 if (spec_dimen_size (as, d, &size) == FAILURE)
1656 {
1657 mpz_clear (*result);
1658 return FAILURE;
1659 }
1660
1661 mpz_mul (*result, *result, size);
1662 mpz_clear (size);
1663 }
1664
1665 return SUCCESS;
1666}
1667
1668
1669/* Get the number of elements in an array section. */
1670
1671static try
1672ref_dimen_size (gfc_array_ref * ar, int dimen, mpz_t * result)
1673{
1674 mpz_t upper, lower, stride;
1675 try t;
1676
1677 if (dimen < 0 || ar == NULL || dimen > ar->dimen - 1)
1678 gfc_internal_error ("ref_dimen_size(): Bad dimension");
1679
1680 switch (ar->dimen_type[dimen])
1681 {
1682 case DIMEN_ELEMENT:
1683 mpz_init (*result);
1684 mpz_set_ui (*result, 1);
1685 t = SUCCESS;
1686 break;
1687
1688 case DIMEN_VECTOR:
1689 t = gfc_array_size (ar->start[dimen], result); /* Recurse! */
1690 break;
1691
1692 case DIMEN_RANGE:
1693 mpz_init (upper);
1694 mpz_init (lower);
1695 mpz_init (stride);
1696 t = FAILURE;
1697
1698 if (ar->start[dimen] == NULL)
1699 {
1700 if (ar->as->lower[dimen] == NULL
1701 || ar->as->lower[dimen]->expr_type != EXPR_CONSTANT)
1702 goto cleanup;
1703 mpz_set (lower, ar->as->lower[dimen]->value.integer);
1704 }
1705 else
1706 {
1707 if (ar->start[dimen]->expr_type != EXPR_CONSTANT)
1708 goto cleanup;
1709 mpz_set (lower, ar->start[dimen]->value.integer);
1710 }
1711
1712 if (ar->end[dimen] == NULL)
1713 {
1714 if (ar->as->upper[dimen] == NULL
1715 || ar->as->upper[dimen]->expr_type != EXPR_CONSTANT)
1716 goto cleanup;
1717 mpz_set (upper, ar->as->upper[dimen]->value.integer);
1718 }
1719 else
1720 {
1721 if (ar->end[dimen]->expr_type != EXPR_CONSTANT)
1722 goto cleanup;
1723 mpz_set (upper, ar->end[dimen]->value.integer);
1724 }
1725
1726 if (ar->stride[dimen] == NULL)
1727 mpz_set_ui (stride, 1);
1728 else
1729 {
1730 if (ar->stride[dimen]->expr_type != EXPR_CONSTANT)
1731 goto cleanup;
1732 mpz_set (stride, ar->stride[dimen]->value.integer);
1733 }
1734
1735 mpz_init (*result);
1736 mpz_sub (*result, upper, lower);
1737 mpz_add (*result, *result, stride);
1738 mpz_div (*result, *result, stride);
1739
1740 /* Zero stride caught earlier. */
1741 if (mpz_cmp_ui (*result, 0) < 0)
1742 mpz_set_ui (*result, 0);
1743 t = SUCCESS;
1744
1745 cleanup:
1746 mpz_clear (upper);
1747 mpz_clear (lower);
1748 mpz_clear (stride);
1749 return t;
1750
1751 default:
1752 gfc_internal_error ("ref_dimen_size(): Bad dimen_type");
1753 }
1754
1755 return t;
1756}
1757
1758
1759static try
1760ref_size (gfc_array_ref * ar, mpz_t * result)
1761{
1762 mpz_t size;
1763 int d;
1764
1765 mpz_init_set_ui (*result, 1);
1766
1767 for (d = 0; d < ar->dimen; d++)
1768 {
1769 if (ref_dimen_size (ar, d, &size) == FAILURE)
1770 {
1771 mpz_clear (*result);
1772 return FAILURE;
1773 }
1774
1775 mpz_mul (*result, *result, size);
1776 mpz_clear (size);
1777 }
1778
1779 return SUCCESS;
1780}
1781
1782
1783/* Given an array expression and a dimension, figure out how many
1784 elements it has along that dimension. Returns SUCCESS if we were
1785 able to return a result in the 'result' variable, FAILURE
1786 otherwise. */
1787
1788try
1789gfc_array_dimen_size (gfc_expr * array, int dimen, mpz_t * result)
1790{
1791 gfc_ref *ref;
1792 int i;
1793
1794 if (dimen < 0 || array == NULL || dimen > array->rank - 1)
1795 gfc_internal_error ("gfc_array_dimen_size(): Bad dimension");
1796
1797 switch (array->expr_type)
1798 {
1799 case EXPR_VARIABLE:
1800 case EXPR_FUNCTION:
1801 for (ref = array->ref; ref; ref = ref->next)
1802 {
1803 if (ref->type != REF_ARRAY)
1804 continue;
1805
1806 if (ref->u.ar.type == AR_FULL)
1807 return spec_dimen_size (ref->u.ar.as, dimen, result);
1808
1809 if (ref->u.ar.type == AR_SECTION)
1810 {
1811 for (i = 0; dimen >= 0; i++)
1812 if (ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1813 dimen--;
1814
1815 return ref_dimen_size (&ref->u.ar, i - 1, result);
1816 }
1817 }
1818
1819 if (spec_dimen_size (array->symtree->n.sym->as, dimen, result) == FAILURE)
1820 return FAILURE;
1821
1822 break;
1823
1824 case EXPR_ARRAY:
1825 if (array->shape == NULL) {
1826 /* Expressions with rank > 1 should have "shape" properly set */
1827 if ( array->rank != 1 )
1828 gfc_internal_error ("gfc_array_dimen_size(): Bad EXPR_ARRAY expr");
1829 return gfc_array_size(array, result);
1830 }
1831
1832 /* Fall through */
1833 default:
1834 if (array->shape == NULL)
1835 return FAILURE;
1836
1837 mpz_init_set (*result, array->shape[dimen]);
1838
1839 break;
1840 }
1841
1842 return SUCCESS;
1843}
1844
1845
1846/* Given an array expression, figure out how many elements are in the
1847 array. Returns SUCCESS if this is possible, and sets the 'result'
1848 variable. Otherwise returns FAILURE. */
1849
1850try
1851gfc_array_size (gfc_expr * array, mpz_t * result)
1852{
1853 expand_info expand_save;
1854 gfc_ref *ref;
1855 int i, flag;
1856 try t;
1857
1858 switch (array->expr_type)
1859 {
1860 case EXPR_ARRAY:
1861 flag = gfc_suppress_error;
1862 gfc_suppress_error = 1;
1863
1864 expand_save = current_expand;
1865
1866 current_expand.count = result;
1867 mpz_init_set_ui (*result, 0);
1868
1869 current_expand.expand_work_function = count_elements;
1870 iter_stack = NULL;
1871
1872 t = expand_constructor (array->value.constructor);
1873 gfc_suppress_error = flag;
1874
1875 if (t == FAILURE)
1876 mpz_clear (*result);
1877 current_expand = expand_save;
1878 return t;
1879
1880 case EXPR_VARIABLE:
1881 for (ref = array->ref; ref; ref = ref->next)
1882 {
1883 if (ref->type != REF_ARRAY)
1884 continue;
1885
1886 if (ref->u.ar.type == AR_FULL)
1887 return spec_size (ref->u.ar.as, result);
1888
1889 if (ref->u.ar.type == AR_SECTION)
1890 return ref_size (&ref->u.ar, result);
1891 }
1892
1893 return spec_size (array->symtree->n.sym->as, result);
1894
1895
1896 default:
1897 if (array->rank == 0 || array->shape == NULL)
1898 return FAILURE;
1899
1900 mpz_init_set_ui (*result, 1);
1901
1902 for (i = 0; i < array->rank; i++)
1903 mpz_mul (*result, *result, array->shape[i]);
1904
1905 break;
1906 }
1907
1908 return SUCCESS;
1909}
1910
1911
1912/* Given an array reference, return the shape of the reference in an
1913 array of mpz_t integers. */
1914
1915try
1916gfc_array_ref_shape (gfc_array_ref * ar, mpz_t * shape)
1917{
1918 int d;
1919 int i;
1920
1921 d = 0;
1922
1923 switch (ar->type)
1924 {
1925 case AR_FULL:
1926 for (; d < ar->as->rank; d++)
1927 if (spec_dimen_size (ar->as, d, &shape[d]) == FAILURE)
1928 goto cleanup;
1929
1930 return SUCCESS;
1931
1932 case AR_SECTION:
1933 for (i = 0; i < ar->dimen; i++)
1934 {
1935 if (ar->dimen_type[i] != DIMEN_ELEMENT)
1936 {
1937 if (ref_dimen_size (ar, i, &shape[d]) == FAILURE)
1938 goto cleanup;
1939 d++;
1940 }
1941 }
1942
1943 return SUCCESS;
1944
1945 default:
1946 break;
1947 }
1948
1949cleanup:
1950 for (d--; d >= 0; d--)
1951 mpz_clear (shape[d]);
1952
1953 return FAILURE;
1954}
1955
1956
1957/* Given an array expression, find the array reference structure that
1958 characterizes the reference. */
1959
1960gfc_array_ref *
1961gfc_find_array_ref (gfc_expr * e)
1962{
1963 gfc_ref *ref;
1964
1965 for (ref = e->ref; ref; ref = ref->next)
1966 if (ref->type == REF_ARRAY
1967 && (ref->u.ar.type == AR_FULL
1968 || ref->u.ar.type == AR_SECTION))
1969 break;
1970
1971 if (ref == NULL)
1972 gfc_internal_error ("gfc_find_array_ref(): No ref found");
1973
1974 return &ref->u.ar;
1975}