OSDN Git Service

* Makefile.am (gfor_helper_src): Split selected_kind.f90.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index ccf2cb7..7ef352e 100644 (file)
@@ -104,6 +104,11 @@ static int enum_overflow;
 
 static location_t current_function_prototype_locus;
 
+/* The argument information structure for the function currently being
+   defined.  */
+
+static GTY(()) tree current_function_arg_info;
+
 /* The current statement tree.  */
 
 static GTY(()) struct stmt_tree_s c_stmt_tree;
@@ -164,6 +169,16 @@ bool c_override_global_bindings_to_false;
    suppress further errors about that identifier in the current
    function.
 
+   The ->type field stores the type of the declaration in this scope;
+   if NULL, the type is the type of the ->decl field.  This is only of
+   relevance for objects with external or internal linkage which may
+   be redeclared in inner scopes, forming composite types that only
+   persist for the duration of those scopes.  In the external scope,
+   this stores the composite of all the types declared for this
+   object, visible or not.  The ->inner_comp field (used only at file
+   scope) stores whether an incomplete array type at file scope was
+   completed at an inner scope to an array size other than 1.
+
    The depth field is copied from the scope structure that holds this
    decl.  It is used to preserve the proper ordering of the ->shadowed
    field (see bind()) and also for a handful of special-case checks.
@@ -176,13 +191,15 @@ bool c_override_global_bindings_to_false;
 struct c_binding GTY((chain_next ("%h.prev")))
 {
   tree decl;                   /* the decl bound */
+  tree type;                   /* the type in this scope */
   tree id;                     /* the identifier it's bound to */
   struct c_binding *prev;      /* the previous decl in this scope */
   struct c_binding *shadowed;  /* the innermost decl shadowed by this one */
   unsigned int depth : 28;      /* depth of this scope */
   BOOL_BITFIELD invisible : 1;  /* normal lookup should ignore this binding */
   BOOL_BITFIELD nested : 1;     /* do not set DECL_CONTEXT when popping */
-  /* two free bits */
+  BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */
+  /* one free bit */
 };
 #define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth)
 #define B_IN_CURRENT_SCOPE(b) ((b)->depth == current_scope->depth)
@@ -436,6 +453,9 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible, bool nested)
   b->depth = scope->depth;
   b->invisible = invisible;
   b->nested = nested;
+  b->inner_comp = 0;
+
+  b->type = 0;
 
   b->prev = scope->bindings;
   scope->bindings = b;
@@ -758,6 +778,12 @@ pop_scope (void)
              && scope != external_scope)
            warning ("%Junused variable `%D'", p, p);
 
+         if (b->inner_comp)
+           {
+             error ("%Jtype of array %qD completed incompatibly with"
+                    " implicit initialization", p, p);
+           }
+
          /* Fall through.  */
        case TYPE_DECL:
        case CONST_DECL:
@@ -797,6 +823,8 @@ pop_scope (void)
              if (I_SYMBOL_BINDING (b->id) != b) abort ();
 #endif
              I_SYMBOL_BINDING (b->id) = b->shadowed;
+             if (b->shadowed && b->shadowed->type)
+               TREE_TYPE (b->shadowed->decl) = b->shadowed->type;
            }
          break;
 
@@ -1357,15 +1385,23 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       else if (!DECL_FILE_SCOPE_P (newdecl))
        {
          if (DECL_EXTERNAL (newdecl))
-           abort ();
+           {
+             /* Extern with initializer at block scope, which will
+                already have received an error.  */
+           }
          else if (DECL_EXTERNAL (olddecl))
-           error ("%Jdeclaration of '%D' with no linkage follows "
-                  "extern declaration", newdecl, newdecl);
+           {
+             error ("%Jdeclaration of '%D' with no linkage follows "
+                    "extern declaration", newdecl, newdecl);
+             locate_old_decl (olddecl, error);
+           }
          else
-           error ("%Jredeclaration of '%D' with no linkage",
-                  newdecl, newdecl);
+           {
+             error ("%Jredeclaration of '%D' with no linkage",
+                    newdecl, newdecl);
+             locate_old_decl (olddecl, error);
+           }
 
-         locate_old_decl (olddecl, error);
          return false;
        }
     }
@@ -1895,6 +1931,9 @@ pushdecl (tree x)
   b = I_SYMBOL_BINDING (name);
   if (b && B_IN_SCOPE (b, scope))
     {
+      if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
+         && COMPLETE_TYPE_P (TREE_TYPE (x)))
+       b->inner_comp = false;
       if (duplicate_decls (x, b->decl))
        return b->decl;
       else
@@ -1915,13 +1954,63 @@ pushdecl (tree x)
      have compatible type; otherwise, the behavior is undefined.)  */
   if (DECL_EXTERNAL (x) || scope == file_scope)
     {
+      tree type = TREE_TYPE (x);
+      tree vistype = 0;
+      tree visdecl = 0;
+      bool type_saved = false;
+      if (b && !B_IN_EXTERNAL_SCOPE (b)
+         && (TREE_CODE (b->decl) == FUNCTION_DECL
+             || TREE_CODE (b->decl) == VAR_DECL)
+         && DECL_FILE_SCOPE_P (b->decl))
+       {
+         visdecl = b->decl;
+         vistype = TREE_TYPE (visdecl);
+       }
       if (warn_nested_externs
          && scope != file_scope
          && !DECL_IN_SYSTEM_HEADER (x))
        warning ("nested extern declaration of '%D'", x);
 
       while (b && !B_IN_EXTERNAL_SCOPE (b))
-       b = b->shadowed;
+       {
+         /* If this decl might be modified, save its type.  This is
+            done here rather than when the decl is first bound
+            because the type may change after first binding, through
+            being completed or through attributes being added.  If we
+            encounter multiple such decls, only the first should have
+            its type saved; the others will already have had their
+            proper types saved and the types will not have changed as
+            their scopes will not have been re-entered.  */
+         if (DECL_FILE_SCOPE_P (b->decl) && !type_saved)
+           {
+             b->type = TREE_TYPE (b->decl);
+             type_saved = true;
+           }
+         if (B_IN_FILE_SCOPE (b)
+             && TREE_CODE (b->decl) == VAR_DECL
+             && TREE_STATIC (b->decl)
+             && TREE_CODE (TREE_TYPE (b->decl)) == ARRAY_TYPE
+             && !TYPE_DOMAIN (TREE_TYPE (b->decl))
+             && TREE_CODE (type) == ARRAY_TYPE
+             && TYPE_DOMAIN (type)
+             && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
+             && !integer_zerop (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
+           {
+             /* Array type completed in inner scope, which should be
+                diagnosed if the completion does not have size 1 and
+                it does not get completed in the file scope.  */
+             b->inner_comp = true;
+           }
+         b = b->shadowed;
+       }
+
+      /* If a matching external declaration has been found, set its
+        type to the composite of all the types of that declaration.
+        After the consistency checks, it will be reset to the
+        composite of the visible types only.  */
+      if (b && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl))
+         && b->type)
+       TREE_TYPE (b->decl) = b->type;
 
       /* The point of the same_translation_unit_p check here is,
         we want to detect a duplicate decl for a construct like
@@ -1932,13 +2021,34 @@ pushdecl (tree x)
          && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl))
          && duplicate_decls (x, b->decl))
        {
+         tree thistype;
+         thistype = (vistype ? composite_type (vistype, type) : type);
+         b->type = TREE_TYPE (b->decl);
+         if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl))
+           thistype
+             = build_type_attribute_variant (thistype,
+                                             TYPE_ATTRIBUTES (b->type));
+         TREE_TYPE (b->decl) = thistype;
          bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true);
          return b->decl;
        }
       else if (TREE_PUBLIC (x))
        {
-         bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false);
-         nested = true;
+         if (visdecl && !b && duplicate_decls (x, visdecl))
+           {
+             /* An external declaration at block scope referring to a
+                visible entity with internal linkage.  The composite
+                type will already be correct for this scope, so we
+                just need to fall through to make the declaration in
+                this scope.  */
+             nested = true;
+           }
+         else
+           {
+             bind (name, x, external_scope, /*invisible=*/true,
+                   /*nested=*/false);
+             nested = true;
+           }
        }
     }
   /* Similarly, a declaration of a function with static linkage at
@@ -2056,7 +2166,16 @@ implicit_decl_warning (tree id, tree olddecl)
 tree
 implicitly_declare (tree functionid)
 {
-  tree decl = lookup_name_in_scope (functionid, external_scope);
+  struct c_binding *b;
+  tree decl = 0;
+  for (b = I_SYMBOL_BINDING (functionid); b; b = b->shadowed)
+    {
+      if (B_IN_SCOPE (b, external_scope))
+       {
+         decl = b->decl;
+         break;
+       }
+    }
 
   if (decl)
     {
@@ -2073,10 +2192,13 @@ implicitly_declare (tree functionid)
        }
       else
        {
+         tree newtype = default_function_type;
+         if (b->type)
+           TREE_TYPE (decl) = b->type;
          /* Implicit declaration of a function already declared
             (somehow) in a different scope, or as a built-in.
             If this is the first time this has happened, warn;
-            then recycle the old declaration.  */
+            then recycle the old declaration but with the new type.  */
          if (!C_DECL_IMPLICIT (decl))
            {
              implicit_decl_warning (functionid, decl);
@@ -2084,21 +2206,27 @@ implicitly_declare (tree functionid)
            }
          if (DECL_BUILT_IN (decl))
            {
-             if (!comptypes (default_function_type, TREE_TYPE (decl)))
+             newtype = build_type_attribute_variant (newtype,
+                                                     TYPE_ATTRIBUTES
+                                                     (TREE_TYPE (decl)));
+             if (!comptypes (newtype, TREE_TYPE (decl)))
                {
                  warning ("incompatible implicit declaration of built-in"
                           " function %qD", decl);
+                 newtype = TREE_TYPE (decl);
                }
            }
          else
            {
-             if (!comptypes (default_function_type, TREE_TYPE (decl)))
+             if (!comptypes (newtype, TREE_TYPE (decl)))
                {
                  error ("incompatible implicit declaration of function %qD",
                         decl);
                  locate_old_decl (decl, error);
                }
            }
+         b->type = TREE_TYPE (decl);
+         TREE_TYPE (decl) = newtype;
          bind (functionid, decl, current_scope,
                /*invisible=*/false, /*nested=*/true);
          return decl;
@@ -2421,7 +2549,7 @@ c_init_decl_processing (void)
   input_location.line = 0;
 #endif
 
-  build_common_tree_nodes (flag_signed_char);
+  build_common_tree_nodes (flag_signed_char, false);
 
   c_common_nodes_and_builtins ();
 
@@ -3153,6 +3281,20 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
     }
 }
 
+/* Given a parsed parameter declaration, decode it into a PARM_DECL.  */
+
+tree
+grokparm (tree parm)
+{
+  tree decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
+                             TREE_PURPOSE (TREE_PURPOSE (parm)),
+                             PARM, false, NULL);
+
+  decl_attributes (&decl, TREE_VALUE (parm), 0);
+
+  return decl;
+}
+
 /* Given a parsed parameter declaration, decode it into a PARM_DECL
    and push that on the current scope.  */
 
@@ -3272,12 +3414,12 @@ complete_array_type (tree type, tree initial_value, int do_default)
            = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
          maxindex = build_int_cst (NULL_TREE,
                                    (TREE_STRING_LENGTH (initial_value)
-                                    / eltsize) - 1, 0);
+                                    / eltsize) - 1);
        }
       else if (TREE_CODE (initial_value) == CONSTRUCTOR)
        {
          tree elts = CONSTRUCTOR_ELTS (initial_value);
-         maxindex = build_int_cst (NULL_TREE, -1, -1);
+         maxindex = build_int_cst (NULL_TREE, -1);
          for (; elts; elts = TREE_CHAIN (elts))
            {
              if (TREE_PURPOSE (elts))
@@ -3294,14 +3436,14 @@ complete_array_type (tree type, tree initial_value, int do_default)
            value = 1;
 
          /* Prevent further error messages.  */
-         maxindex = build_int_cst (NULL_TREE, 0, 0);
+         maxindex = build_int_cst (NULL_TREE, 0);
        }
     }
 
   if (!maxindex)
     {
       if (do_default)
-       maxindex = build_int_cst (NULL_TREE, 0, 0);
+       maxindex = build_int_cst (NULL_TREE, 0);
       value = 2;
     }
 
@@ -3412,7 +3554,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
     {
       error ("width of `%s' exceeds its type", name);
       w = max_width;
-      *width = build_int_cst (NULL_TREE, w, 0);
+      *width = build_int_cst (NULL_TREE, w);
     }
   else
     w = tree_low_cst (*width, 1);
@@ -4567,10 +4709,9 @@ grokdeclarator (tree declarator, tree declspecs,
          = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
 
        /* For a function definition, record the argument information
-          block in DECL_ARGUMENTS where store_parm_decls will look
-          for it.  */
+          block where store_parm_decls will look for it.  */
        if (funcdef_flag)
-         DECL_ARGUMENTS (decl) = arg_info;
+         current_function_arg_info = arg_info;
 
        if (defaulted_int)
          C_FUNCTION_IMPLICIT_INT (decl) = 1;
@@ -6215,16 +6356,18 @@ void
 store_parm_decls (void)
 {
   tree fndecl = current_function_decl;
+  bool proto;
 
   /* The argument information block for FNDECL.  */
-  tree arg_info = DECL_ARGUMENTS (fndecl);
+  tree arg_info = current_function_arg_info;
+  current_function_arg_info = 0;
 
   /* True if this definition is written with a prototype.  Note:
      despite C99 6.7.5.3p14, we can *not* treat an empty argument
      list in a function definition as equivalent to (void) -- an
      empty argument list specifies the function has no parameters,
      but only (void) sets up a prototype for future calls.  */
-  bool proto = ARG_INFO_TYPES (arg_info) != 0;
+  proto = ARG_INFO_TYPES (arg_info) != 0;
 
   if (proto)
     store_parm_decls_newstyle (fndecl, arg_info);
@@ -6508,6 +6651,7 @@ c_push_function_context (struct function *f)
   p->x_break_label = c_break_label;
   p->x_cont_label = c_cont_label;
   p->x_switch_stack = c_switch_stack;
+  p->arg_info = current_function_arg_info;
   p->returns_value = current_function_returns_value;
   p->returns_null = current_function_returns_null;
   p->returns_abnormally = current_function_returns_abnormally;
@@ -6536,6 +6680,7 @@ c_pop_function_context (struct function *f)
   c_break_label = p->x_break_label;
   c_cont_label = p->x_cont_label;
   c_switch_stack = p->x_switch_stack;
+  current_function_arg_info = p->arg_info;
   current_function_returns_value = p->returns_value;
   current_function_returns_null = p->returns_null;
   current_function_returns_abnormally = p->returns_abnormally;