OSDN Git Service

(tablejump_internal4+1): Fix typo in condition.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index 65dfa01..c89ee1d 100644 (file)
@@ -411,16 +411,20 @@ tree static_ctors, static_dtors;
 
 /* Forward declarations.  */
 
-static tree grokparms (), grokdeclarator ();
-tree pushdecl ();
-tree builtin_function ();
-void shadow_tag_warned ();
-
-static tree lookup_tag ();
-static tree lookup_tag_reverse ();
-tree lookup_name_current_level ();
-static char *redeclaration_error_message ();
-static void layout_array_type ();
+static struct binding_level * make_binding_level       PROTO((void));
+static void clear_limbo_values         PROTO((tree));
+static int duplicate_decls             PROTO((tree, tree, int));
+static char *redeclaration_error_message PROTO((tree, tree));
+static void storedecls                 PROTO((tree));
+static void storetags                  PROTO((tree));
+static tree lookup_tag                 PROTO((enum tree_code, tree,
+                                              struct binding_level *, int));
+static tree lookup_tag_reverse         PROTO((tree));
+static tree grokdeclarator             PROTO((tree, tree, enum decl_context,
+                                              int));
+static tree grokparms                  PROTO((tree, int));
+static int field_decl_cmp              PROTO((tree *, tree *));
+static void layout_array_type          PROTO((tree));
 \f
 /* C-specific option variables.  */
 
@@ -902,6 +906,22 @@ pushlevel (tag_transparent)
   keep_next_if_subblocks = 0;
 }
 
+/* Clear the limbo values of all identifiers defined in BLOCK or a subblock. */
+
+static void
+clear_limbo_values (block)
+     tree block;
+{
+  tree tem;
+
+  for (tem = BLOCK_VARS (block); tem; tem = TREE_CHAIN (tem))
+    if (DECL_NAME (tem) != 0)
+      IDENTIFIER_LIMBO_VALUE (DECL_NAME (tem)) = 0;
+
+  for (tem = BLOCK_SUBBLOCKS (block); tem; tem = TREE_CHAIN (tem))
+    clear_limbo_values (tem);
+}
+    
 /* Exit a binding level.
    Pop the level off, and restore the state of the identifier-decl mappings
    that were in effect when this level was entered.
@@ -1055,6 +1075,8 @@ poplevel (keep, reverse, functionbody)
 
   if (functionbody)
     {
+      clear_limbo_values (block);
+
       /* If this is the top level block of a function,
         the vars are the function's parameters.
         Don't leave them in the BLOCK because they are
@@ -1843,6 +1865,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
       DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
       /* An extern decl does not override previous storage class.  */
       TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
+      if (! DECL_EXTERNAL (newdecl))
+       DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
     }
   else
     {
@@ -3591,9 +3615,13 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
   if (TREE_CODE (decl) == FUNCTION_DECL)
     gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0);
 
-  /* For C and Objective-C, we by default put things in .common when
-     possible.  */
-  DECL_COMMON (decl) = 1;
+  /* ANSI specifies that a tentative definition which is not merged with
+     a non-tentative definition behaves exactly like a definition with an
+     initializer equal to zero.  (Section 3.7.2)
+     -fno-common gives strict ANSI behavior.  Usually you don't want it.
+     This matters only for variables with external linkage.  */
+  if (! flag_no_common)
+    DECL_COMMON (decl) = 1;
 
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
   decl_attributes (decl, attributes, prefix_attributes);
@@ -5407,6 +5435,7 @@ start_struct (code, name)
   ref = make_node (code);
   pushtag (name, ref);
   C_TYPE_BEING_DEFINED (ref) = 1;
+  TYPE_PACKED (ref) = flag_pack_struct;
   return ref;
 }
 
@@ -5834,6 +5863,9 @@ start_enum (name)
   enum_next_value = integer_zero_node;
   enum_overflow = 0;
 
+  if (flag_short_enums)
+    TYPE_PACKED (enumtype) = 1;
+
   return enumtype;
 }
 
@@ -5890,10 +5922,17 @@ finish_enum (enumtype, values, attributes)
   highprec = min_precision (maxnode, TREE_UNSIGNED (enumtype));
   precision = MAX (lowprec, highprec);
 
-  if (flag_short_enums || TYPE_PACKED (enumtype)
-      || precision > TYPE_PRECISION (integer_type_node))
-    /* Use the width of the narrowest normal C type which is wide enough.  */
-    TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size (precision, 1));
+  if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
+    {
+      tree narrowest = type_for_size (precision, 1);
+      if (narrowest == 0)
+       {
+         warning ("enumeration values exceed range of largest integer");
+         narrowest = long_long_integer_type_node;
+       }
+
+      TYPE_PRECISION (enumtype) = TYPE_PRECISION (narrowest);
+    }
   else
     TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
 
@@ -6758,7 +6797,9 @@ combine_parm_decls (specparms, parmlist, void_at_end)
   
   if (void_at_end)
     return saveable_tree_cons (parmdecls, nonparms,
-                              nreverse (saveable_tree_cons (NULL_TREE, void_type_node, types)));
+                              nreverse (saveable_tree_cons (NULL_TREE,
+                                                            void_type_node,
+                                                            types)));
 
   return saveable_tree_cons (parmdecls, nonparms, nreverse (types));
 }
@@ -6795,19 +6836,19 @@ finish_function (nested)
       setjmp_protect_args ();
     }
 
-#ifdef DEFAULT_MAIN_RETURN
   if (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main"))
     {
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
          != integer_type_node)
-       warning_with_decl (fndecl, "return type of `%s' is not `int'");
+       pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
       else
        {
+#ifdef DEFAULT_MAIN_RETURN
          /* Make it so that `main' always returns success by default.  */
          DEFAULT_MAIN_RETURN;
+#endif
        }
     }
-#endif
 
   /* Generate rtl for function exit.  */
   expand_function_end (input_filename, lineno, 0);