OSDN Git Service

(set_init_index): Add pedantic warning.
authorrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Jul 1993 05:57:26 +0000 (05:57 +0000)
committerrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Jul 1993 05:57:26 +0000 (05:57 +0000)
(set_init_label): Likewise.

(digest_init): Add `static' to definition.

(start_init): Fill in p->next.

Handle gaps in record initializers.
(constructor_bit_index): New variable.
(constructor_stack): New field bit_index.
(really_start_incremental_init, push_init_level): Save and init it.
(pop_init_level): Restore it.
(output_init_element): Update constructor_bit_index.
Use it to output gaps.
(pop_init_level): Speed up by using constructor_bit_index.

(process_init_element): Accept STRING_CST for subarray.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@4997 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/c-typeck.c

index f8702e2..fe459d9 100644 (file)
@@ -4831,7 +4831,7 @@ static tree free_tree_list = NULL_TREE;
    If OFWHAT is null, the component name is stored on the spelling stack.
    (That is true for all nested calls to digest_init.)  */
 
-tree
+static tree
 digest_init (type, init, tail, require_constant, constructor_constant)
      tree type, init, *tail;
      int require_constant, constructor_constant;
@@ -5081,6 +5081,11 @@ static tree constructor_unfilled_fields;
    This is a special INTEGER_CST node that we modify in place.  */
 static tree constructor_unfilled_index;
 
+/* In a RECORD_TYPE, the byte index of the next consecutive field.
+   This is so we can generate gaps between fields, when appropriate.
+   This is a special INTEGER_CST node that we modify in place.  */
+static tree constructor_bit_index;
+
 /* If we are saving up the elements rather than allocating them,
    this is the list of elements so far (in reverse order,
    most recent first).  */
@@ -5131,6 +5136,10 @@ static int constructor_top_level;
 /* When we finish reading a constructor expression
    (constructor_decl is 0), the CONSTRUCTOR goes here.  */
 static tree constructor_result;
+\f
+/* This stack has a level for each implicit or explicit level of
+   structuring in the initializer, including the outermost one.  It
+   saves the values of most of the variables above.  */
 
 struct constructor_stack
 {
@@ -5142,6 +5151,7 @@ struct constructor_stack
   tree max_index;
   tree unfilled_index;
   tree unfilled_fields;
+  tree bit_index;
   tree elements;
   int offset;
   tree pending_elts;
@@ -5205,7 +5215,7 @@ start_init (decl, asmspec_tree, top_level)
   p->spelling_size = spelling_size;
   p->deferred = constructor_subconstants_deferred;
   p->top_level = constructor_top_level;
-  p->next = 0;
+  p->next = initializer_stack;
   initializer_stack = p;
 
   constructor_decl = decl;
@@ -5302,6 +5312,7 @@ really_start_incremental_init (type)
   p->max_index = constructor_max_index;
   p->unfilled_index = constructor_unfilled_index;
   p->unfilled_fields = constructor_unfilled_fields;
+  p->bit_index = constructor_bit_index;
   p->elements = 0;
   p->constant = constructor_constant;
   p->simple = constructor_simple;
@@ -5326,6 +5337,7 @@ really_start_incremental_init (type)
     {
       constructor_fields = TYPE_FIELDS (constructor_type);
       constructor_unfilled_fields = constructor_fields;
+      constructor_bit_index = copy_node (integer_zero_node);
     }
   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
     {
@@ -5381,6 +5393,7 @@ push_init_level (implicit)
   p->max_index = constructor_max_index;
   p->unfilled_index = constructor_unfilled_index;
   p->unfilled_fields = constructor_unfilled_fields;
+  p->bit_index = constructor_bit_index;
   p->elements = constructor_elements;
   p->constant = constructor_constant;
   p->simple = constructor_simple;
@@ -5419,6 +5432,7 @@ push_init_level (implicit)
     {
       constructor_fields = TYPE_FIELDS (constructor_type);
       constructor_unfilled_fields = constructor_fields;
+      constructor_bit_index = copy_node (integer_zero_node);
     }
   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
     {
@@ -5488,6 +5502,15 @@ pop_init_level (implicit)
   /* Now output all pending elements.  */
   output_pending_init_elements (1);
 
+#if 0 /* c-parse.in warns about {}.  */
+  /* In ANSI, each brace level must have at least one element.  */
+  if (! implicit && pedantic
+      && (TREE_CODE (constructor_type) == ARRAY_TYPE
+         ? integer_zerop (constructor_unfilled_index)
+         : constructor_unfilled_fields == TYPE_FIELDS (constructor_type)))
+    pedwarn_init ("empty braces in initializer%s", " for `%s'", NULL);
+#endif
+
   /* Pad out the end of the structure.  */
   
   if (! constructor_incremental)
@@ -5515,17 +5538,9 @@ pop_init_level (implicit)
       if (TREE_CODE (constructor_type) == RECORD_TYPE
          || TREE_CODE (constructor_type) == UNION_TYPE)
        {
-         tree tail;
-         /* Find the last field written out.  */
-         for (tail = TYPE_FIELDS (constructor_type); tail;
-              tail = TREE_CHAIN (tail))
-           if (TREE_CHAIN (tail) == constructor_unfilled_fields)
-             break;
          /* Find the offset of the end of that field.  */
          filled = size_binop (CEIL_DIV_EXPR,
-                              size_binop (PLUS_EXPR,
-                                          DECL_FIELD_BITPOS (tail),
-                                          DECL_SIZE (tail)),
+                              constructor_bit_index,
                               size_int (BITS_PER_UNIT));
        }
       else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
@@ -5581,6 +5596,7 @@ pop_init_level (implicit)
   constructor_max_index = p->max_index;
   constructor_unfilled_index = p->unfilled_index;
   constructor_unfilled_fields = p->unfilled_fields;
+  constructor_bit_index = p->bit_index;
   constructor_elements = p->elements;
   constructor_constant = p->constant;
   constructor_simple = p->simple;
@@ -5622,7 +5638,11 @@ set_init_index (first, last)
       if (last != 0 && tree_int_cst_lt (last, first))
        error_init ("empty index range in initializer%s", " for `%s'", NULL);
       else
-       constructor_range_end = last;
+       {
+         if (pedantic)
+           pedwarn ("ANSI C forbids specifying element to initialize");
+         constructor_range_end = last;
+       }
     }
 }
 
@@ -5651,7 +5671,11 @@ set_init_label (fieldname)
     error ("field `%s' already initialized",
           IDENTIFIER_POINTER (fieldname));
   else
-    constructor_fields = tail;
+    {
+      constructor_fields = tail;
+      if (pedantic)
+       pedwarn ("ANSI C forbids specifying structure member to initialize");
+    }
 }
 \f
 /* "Output" the next constructor element.
@@ -5759,7 +5783,37 @@ output_init_element (value, type, field, pending)
                                        require_constant_elements),
                           constructor_elements);
          else
-           output_constant (value, int_size_in_bytes (type));
+           {
+             /* Structure elements may require alignment.
+                Do this, if necessary.  */
+             if (TREE_CODE (constructor_type) == RECORD_TYPE)
+               {
+                 /* Advance to offset of this element.  */
+                 if (! tree_int_cst_equal (constructor_bit_index,
+                                           DECL_FIELD_BITPOS (constructor_fields)))
+                   {
+                     int next = (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
+                                 / BITS_PER_UNIT);
+                     int here = (TREE_INT_CST_LOW (constructor_bit_index)
+                                 / BITS_PER_UNIT);
+
+                     assemble_zeros (next - here);
+                   }
+               }
+             output_constant (value, int_size_in_bytes (type));
+
+             /* For a record, keep track of end position of last field.  */
+             if (TREE_CODE (constructor_type) == RECORD_TYPE)
+               {
+                 tree temp = size_binop (PLUS_EXPR,
+                                         DECL_FIELD_BITPOS (constructor_fields),
+                                         DECL_SIZE (constructor_fields));
+                 TREE_INT_CST_LOW (constructor_bit_index)
+                   = TREE_INT_CST_LOW (temp);
+                 TREE_INT_CST_HIGH (constructor_bit_index)
+                   = TREE_INT_CST_HIGH (temp);
+               }
+           }
        }
 
       /* Advance the variable that indicates sequential elements output.  */
@@ -5924,6 +5978,9 @@ void
 process_init_element (value)
      tree value;
 {
+  tree orig_value = value;
+  int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
+
   if (value != 0)
     value = default_conversion (value);
 
@@ -5968,9 +6025,18 @@ process_init_element (value)
          fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields));
          fieldcode = TREE_CODE (fieldtype);
 
-         if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
-             && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
-                 || fieldcode == UNION_TYPE))
+         /* Accept a string constant to initialize a subarray.  */
+         if (value != 0
+             && fieldcode == ARRAY_TYPE
+             && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
+             && string_flag)
+           value = orig_value;
+         /* Otherwise, if we have come to a subaggregate,
+            and we don't have an element of its type, push into it.  */
+         else if (value != 0
+                  && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
+                  && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
+                      || fieldcode == UNION_TYPE))
            {
              push_init_level (1);
              continue;
@@ -5983,10 +6049,20 @@ process_init_element (value)
              RESTORE_SPELLING_DEPTH (constructor_depth);
            }
          else
-           /* If we are doing the bookkeeping for an element that was
-              directly output as a constructor,
-              we must update constructor_unfilled_fields.  */
-           constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
+           /* Do the bookkeeping for an element that was
+              directly output as a constructor.  */
+           {
+             /* For a record, keep track of end position of last field.  */
+             tree temp = size_binop (PLUS_EXPR,
+                                     DECL_FIELD_BITPOS (constructor_fields),
+                                     DECL_SIZE (constructor_fields));
+             TREE_INT_CST_LOW (constructor_bit_index)
+               = TREE_INT_CST_LOW (temp);
+             TREE_INT_CST_HIGH (constructor_bit_index)
+               = TREE_INT_CST_HIGH (temp);
+
+             constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
+           }
 
          constructor_fields = TREE_CHAIN (constructor_fields);
          break;
@@ -6006,9 +6082,18 @@ process_init_element (value)
          fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields));
          fieldcode = TREE_CODE (fieldtype);
 
-         if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
-             && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
-                 || fieldcode == UNION_TYPE))
+         /* Accept a string constant to initialize a subarray.  */
+         if (value != 0
+             && fieldcode == ARRAY_TYPE
+             && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
+             && string_flag)
+           value = orig_value;
+         /* Otherwise, if we have come to a subaggregate,
+            and we don't have an element of its type, push into it.  */
+         else if (value != 0
+                  && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
+                  && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
+                      || fieldcode == UNION_TYPE))
            {
              push_init_level (1);
              continue;
@@ -6034,9 +6119,18 @@ process_init_element (value)
          tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
          enum tree_code eltcode = TREE_CODE (elttype);
 
-         if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype
-             && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
-                 || eltcode == UNION_TYPE))
+         /* Accept a string constant to initialize a subarray.  */
+         if (value != 0
+             && eltcode == ARRAY_TYPE
+             && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE
+             && string_flag)
+           value = orig_value;
+         /* Otherwise, if we have come to a subaggregate,
+            and we don't have an element of its type, push into it.  */
+         else if (value != 0
+                  && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype
+                  && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
+                      || eltcode == UNION_TYPE))
            {
              push_init_level (1);
              continue;