OSDN Git Service

* dependency.c (gfc_check_dependency): Remove unused vars and nvars
[pf3gnuchains/gcc-fork.git] / gcc / fortran / array.c
index a7081d8..9491406 100644 (file)
@@ -1,5 +1,5 @@
 /* Array things
-   Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Andy Vaught
 
 This file is part of GCC.
@@ -16,21 +16,19 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
+#include "system.h"
 #include "gfortran.h"
 #include "match.h"
 
-#include <string.h>
-#include <assert.h>
-
 /* This parameter is the size of the largest array constructor that we
    will expand to an array constructor without iterators.
    Constructors larger than this will remain in the iterator form.  */
 
-#define GFC_MAX_AC_EXPAND 100
+#define GFC_MAX_AC_EXPAND 65535
 
 
 /**************** Array reference matching subroutines *****************/
@@ -171,8 +169,8 @@ gfc_match_array_ref (gfc_array_ref * ar, gfc_array_spec * as, int init)
        }
     }
 
-  gfc_error ("Array reference at %C cannot have more than "
-            stringize (GFC_MAX_DIMENSIONS) " dimensions");
+  gfc_error ("Array reference at %C cannot have more than %d dimensions",
+            GFC_MAX_DIMENSIONS);
 
 error:
   return MATCH_ERROR;
@@ -421,8 +419,8 @@ gfc_match_array_spec (gfc_array_spec ** asp)
 
       if (as->rank >= GFC_MAX_DIMENSIONS)
        {
-         gfc_error ("Array specification at %C has more than "
-                    stringize (GFC_MAX_DIMENSIONS) " dimensions");
+         gfc_error ("Array specification at %C has more than %d dimensions",
+                    GFC_MAX_DIMENSIONS);
          goto cleanup;
        }
 
@@ -459,7 +457,7 @@ gfc_set_array_spec (gfc_symbol * sym, gfc_array_spec * as, locus * error_loc)
   if (as == NULL)
     return SUCCESS;
 
-  if (gfc_add_dimension (&sym->attr, error_loc) == FAILURE)
+  if (gfc_add_dimension (&sym->attr, sym->name, error_loc) == FAILURE)
     return FAILURE;
 
   sym->as = as;
@@ -868,15 +866,31 @@ gfc_match_array_constructor (gfc_expr ** result)
   gfc_expr *expr;
   locus where;
   match m;
+  const char *end_delim;
 
   if (gfc_match (" (/") == MATCH_NO)
-    return MATCH_NO;
+    {
+      if (gfc_match (" [") == MATCH_NO)
+        return MATCH_NO;
+      else
+        {
+          if (gfc_notify_std (GFC_STD_F2003, "New in Fortran 2003: [...] "
+                              "style array constructors at %C") == FAILURE)
+            return MATCH_ERROR;
+          end_delim = " ]";
+        }
+    }
+  else
+    end_delim = " /)";
 
   where = gfc_current_locus;
   head = tail = NULL;
 
-  if (gfc_match (" /)") == MATCH_YES)
-    goto empty;                        /* Special case */
+  if (gfc_match (end_delim) == MATCH_YES)
+    {
+      gfc_error ("Empty array constructor at %C is not allowed");
+      goto cleanup;
+    }
 
   for (;;)
     {
@@ -897,10 +911,9 @@ gfc_match_array_constructor (gfc_expr ** result)
        break;
     }
 
-  if (gfc_match (" /)") == MATCH_NO)
+  if (gfc_match (end_delim) == MATCH_NO)
     goto syntax;
 
-empty:
   expr = gfc_get_expr ();
 
   expr->expr_type = EXPR_ARRAY;
@@ -942,7 +955,7 @@ check_element_type (gfc_expr * expr)
 {
 
   if (cons_state == CONS_BAD)
-    return 0;                  /* Supress further errors */
+    return 0;                  /* Suppress further errors */
 
   if (cons_state == CONS_START)
     {
@@ -969,7 +982,7 @@ check_element_type (gfc_expr * expr)
 }
 
 
-/* Recursive work function for gfc_check_constructor_type(). */
+/* Recursive work function for gfc_check_constructor_type().  */
 
 static try
 check_constructor_type (gfc_constructor * c)
@@ -1491,7 +1504,7 @@ resolve_array_list (gfc_constructor * p)
   for (; p; p = p->next)
     {
       if (p->iterator != NULL
-         && gfc_resolve_iterator (p->iterator) == FAILURE)
+         && gfc_resolve_iterator (p->iterator, false) == FAILURE)
        t = FAILURE;
 
       if (gfc_resolve_expr (p->expr) == FAILURE)
@@ -1501,9 +1514,50 @@ resolve_array_list (gfc_constructor * p)
   return t;
 }
 
+/* Resolve character array constructor. If it is a constant character array and
+   not specified character length, update character length to the maximum of
+   its element constructors' length.  */
+
+static void
+resolve_character_array_constructor (gfc_expr * expr)
+{
+  gfc_constructor * p;
+  int max_length;
+
+  gcc_assert (expr->expr_type == EXPR_ARRAY);
+  gcc_assert (expr->ts.type == BT_CHARACTER);
+
+  max_length = -1;
+
+  if (expr->ts.cl == NULL)
+    {
+      expr->ts.cl = gfc_get_charlen ();
+      expr->ts.cl->next = gfc_current_ns->cl_list;
+      gfc_current_ns->cl_list = expr->ts.cl;
+    }
+
+  if (expr->ts.cl->length == NULL)
+    {
+      /* Find the maximum length of the elements. Do nothing for variable array
+        constructor.  */
+      for (p = expr->value.constructor; p; p = p->next)
+       if (p->expr->expr_type == EXPR_CONSTANT)
+         max_length = MAX (p->expr->value.character.length, max_length);
+       else
+         return;
+
+      if (max_length != -1)
+       {
+         /* Update the character length of the array constructor.  */
+         expr->ts.cl->length = gfc_int_expr (max_length);
+         /* Update the element constructors.  */
+         for (p = expr->value.constructor; p; p = p->next)
+           gfc_set_constant_character_len (max_length, p->expr);
+       }
+    }
+}
 
-/* Resolve all of the expressions in an array list.
-   TODO: String lengths.  */
+/* Resolve all of the expressions in an array list.  */
 
 try
 gfc_resolve_array_constructor (gfc_expr * expr)
@@ -1513,6 +1567,8 @@ gfc_resolve_array_constructor (gfc_expr * expr)
   t = resolve_array_list (expr->value.constructor);
   if (t == SUCCESS)
     t = gfc_check_constructor_type (expr);
+  if (t == SUCCESS && expr->ts.type == BT_CHARACTER)
+    resolve_character_array_constructor (expr);
 
   return t;
 }
@@ -1608,9 +1664,9 @@ gfc_get_array_element (gfc_expr * array, int element)
 
 /********* Subroutines for determining the size of an array *********/
 
-/* These are needed just to accomodate RESHAPE().  There are no
+/* These are needed just to accommodate RESHAPE().  There are no
    diagnostics here, we just return a negative number if something
-   goes wrong. */
+   goes wrong.  */
 
 
 /* Get the size of single dimension of an array specification.  The
@@ -1973,3 +2029,22 @@ gfc_find_array_ref (gfc_expr * e)
 
   return &ref->u.ar;
 }
+
+
+/* Find out if an array shape is known at compile time.  */
+
+int
+gfc_is_compile_time_shape (gfc_array_spec *as)
+{
+  int i;
+
+  if (as->type != AS_EXPLICIT)
+    return 0;
+
+  for (i = 0; i < as->rank; i++)
+    if (!gfc_is_constant_expr (as->lower[i])
+       || !gfc_is_constant_expr (as->upper[i]))
+      return 0;
+
+  return 1;
+}