re PR c++/80 (g++ enum and attributed __packed__)
authorBen Elliston <bje@redhat.com>
Wed, 11 Jul 2001 07:56:23 +0000 (07:56 +0000)
committerBen Elliston <bje@gcc.gnu.org>
Wed, 11 Jul 2001 07:56:23 +0000 (17:56 +1000)
2001-07-11  Ben Elliston  <bje@redhat.com>

PR c++/80
* decl.c (finish_enum): New "attributes" argument; pass it to
cplus_decl_attributes.  Use a narrower type if the enum is packed.
* cp-tree.h (finish_enum): Adjust prototype.
* parse.y (enum_head): New non-terminal.
(structsp): Use it. Enums now may be preceded or followed by
optional attributes -- pass their chained tree to finish_enum().
* pt.c (tsubst_enum): Pass NULL_TREE for the new argument.

From-SVN: r43929

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parse.y
gcc/cp/pt.c

index d7a843f8ad5eee45c1924377a9097fcfeb80806c..4ecf0aa0bce7d5de6c518f3609fe8f155785b10e 100644 (file)
@@ -1,3 +1,14 @@
+2001-07-11  Ben Elliston  <bje@redhat.com>
+
+       PR c++/80
+       * decl.c (finish_enum): New "attributes" argument; pass it to
+       cplus_decl_attributes.  Use a narrower type if the enum is packed.
+       * cp-tree.h (finish_enum): Adjust prototype.
+       * parse.y (enum_head): New non-terminal.
+       (structsp): Use it. Enums now may be preceded or followed by
+       optional attributes -- pass their chained tree to finish_enum().
+       * pt.c (tsubst_enum): Pass NULL_TREE for the new argument.
+
 2001-07-10  Mark Mitchell  <mark@codesourcery.com>
 
        * pt.c (tsubst_decl): Set DECL_CONTEXT for namespace-scope
index 66ce4fb0d31418aebb26bde50f84fdbb410753ce..d27ee9fe830a4240bcb1b681c546b8a023f445f1 100644 (file)
@@ -3845,7 +3845,7 @@ extern tree xref_tag                              PARAMS ((tree, tree, int));
 extern tree xref_tag_from_type                 PARAMS ((tree, tree, int));
 extern void xref_basetypes                     PARAMS ((tree, tree, tree, tree));
 extern tree start_enum                         PARAMS ((tree));
-extern void finish_enum                                PARAMS ((tree));
+extern void finish_enum                                PARAMS ((tree, tree));
 extern void build_enumerator                   PARAMS ((tree, tree, tree));
 extern int start_function                      PARAMS ((tree, tree, tree, int));
 extern tree finish_function                    PARAMS ((int));
index 5de715086267d8f4cc9e73ffe03d0fcb8d91878a..15ee0be1a39893551e66f85a22f04e88ceb0857d 100644 (file)
@@ -12984,8 +12984,9 @@ start_enum (name)
    ENUMTYPE is the type object and VALUES a list of name-value pairs.  */
 
 void
-finish_enum (enumtype)
+finish_enum (enumtype, attributes)
      tree enumtype;
+     tree attributes;
 {
   tree pair;
   tree minnode;
@@ -12996,6 +12997,8 @@ finish_enum (enumtype)
   int highprec; 
   int precision;
 
+  cplus_decl_attributes (enumtype, attributes, NULL_TREE);
+  
   /* We built up the VALUES in reverse order.  */
   TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
 
@@ -13074,11 +13077,14 @@ finish_enum (enumtype)
   else
     fixup_signed_type (enumtype);
 
-  if (flag_short_enums || (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 (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));
+    }
   else
     TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
 
index 6e2ac183ce55685f87ee308b47f984753480731c..6c2a6beb24bcbe0ed00e41bc254e25bbd0cc8fe2 100644 (file)
@@ -340,7 +340,7 @@ cp_parse_init ()
 %type <ttype> init initlist maybeasm maybe_init defarg defarg1
 %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
 %type <ttype> maybe_attribute attributes attribute attribute_list attrib
-%type <ttype> any_word
+%type <ttype> any_word enum_head
 
 %type <itype> save_lineno
 %type <ttype> simple_stmt simple_if
@@ -2240,22 +2240,29 @@ pending_defargs:
                { do_pending_defargs (); }
        ;
 
+enum_head:
+         ENUM
+               { $$ = NULL_TREE; }
+       | ENUM attributes
+               { $$ = $2; }
+       ;
+
 structsp:
-         ENUM identifier '{'
+         enum_head identifier '{'
                { $<ttype>$ = current_enum_type;
                  current_enum_type = start_enum ($2); }
-         enumlist_opt '}'
+         enumlist_opt '}' maybe_attribute 
                { $$.t = current_enum_type;
-                 finish_enum (current_enum_type);
+                 finish_enum (current_enum_type, chainon ($1, $7));
                  $$.new_type_flag = 1;
                  current_enum_type = $<ttype>4;
                  check_for_missing_semicolon ($$.t); }
-       | ENUM '{'
+       | enum_head '{'
                { $<ttype>$ = current_enum_type;
                  current_enum_type = start_enum (make_anon_name ()); }
-         enumlist_opt '}'
+         enumlist_opt '}' maybe_attribute 
                 { $$.t = current_enum_type;
-                 finish_enum (current_enum_type);
+                 finish_enum (current_enum_type, chainon ($1, $6));
                  $$.new_type_flag = 1;
                  current_enum_type = $<ttype>3;
                  check_for_missing_semicolon ($$.t); }
index 3d6279a82823dd81224999c839c7ce80130b896c..9503e3ec13f6edd26df427d1a317bceada60a65d 100644 (file)
@@ -10149,7 +10149,7 @@ tsubst_enum (tag, newtag, args)
       build_enumerator (TREE_PURPOSE (e), value, newtag); 
     }
 
-  finish_enum (newtag);
+  finish_enum (newtag, NULL_TREE);
   DECL_SOURCE_LINE (TYPE_NAME (newtag)) = DECL_SOURCE_LINE (TYPE_NAME (tag));
   DECL_SOURCE_FILE (TYPE_NAME (newtag)) = DECL_SOURCE_FILE (TYPE_NAME (tag));
 }