home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.g++.bug
- Path: sparky!uunet!cis.ohio-state.edu!kelvin.seas.virginia.edu!gs4t
- From: gs4t@kelvin.seas.virginia.edu (Gnanasekaran Swaminathan)
- Subject: Fix for class local enum bug
- Message-ID: <9212310357.AA48953@kelvin.seas.Virginia.EDU>
- Sender: gnulists@ai.mit.edu
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Wed, 30 Dec 1992 17:57:38 GMT
- Approved: bug-g++@prep.ai.mit.edu
- Lines: 150
-
- A patch that fixes the following two bugs in gcc-2.3.3 follows:
-
- Bug1: gcc2.3.3 does not let member functions of nested classes
- to define its own local classes and enum.
-
- Bug2: gcc2.3.3 does not define a class local enum as soon as it is
- supposed to be defined. See ARM p114 for details.
-
- example:
- struct A {
- struct B {
- int f() {
- enum { a=1, b=3 }; // Bug1. fails without the patch
- struct C { int j; }; // Bug1. fails without the patch
- return a*b;
- }
- };
- enum { a = 3, b = a*4 }; // Bug2. fails without the patch
- };
-
- ChangeLog:
-
- Wed Dec 30 22:22:32 EST 1992 Gnanasekaran Swaminathan (gs4t@virginia.edu)
-
- * cp-decl.c (lookup_nested_type): Next context is RECORD_TYPE
- in case of local classes in member functions of nested classes.
- So, get the type decl from TREE_CHAIN (context) as the next context.
- (classlocal_enum_decls): A new static variable is introduced.
- (start_enum): Tag of enumtype is made addressable as soon as one is
- pushed. (build_enumerator): A class local enumerator is declared
- as soon as the name and its initializer are seen (cf. ARM p114).
- (grok_enum_decls): Cleaned up as most of its code are moved to
- build_enumerator now.
-
- *** cp-decl.c.orig Mon Dec 28 18:33:18 1992
- --- cp-decl.c Wed Dec 30 22:08:12 1992
- ***************
- *** 3753,3756 ****
- --- 3753,3758 ----
- return TREE_VALUE (match);
- context = DECL_CONTEXT (context);
- + if (context && TREE_CODE (context) == RECORD_TYPE)
- + context = TREE_CHAIN (context);
- }
- break;
- ***************
- *** 9390,9393 ****
- --- 9392,9397 ----
- }
-
- + static tree classlocal_enum_decls = NULL_TREE;
- +
- /* Begin compiling the definition of an enumeration type.
- NAME is its name (or null if anonymous).
- ***************
- *** 9415,9420 ****
- --- 9419,9429 ----
- enumtype = make_node (ENUMERAL_TYPE);
- pushtag (name, enumtype);
- +
- + if (current_class_type != NULL_TREE)
- + TREE_ADDRESSABLE (b->tags) = 1;
- }
-
- + classlocal_enum_decls = NULL_TREE;
- +
- if (TYPE_VALUES (enumtype) != 0)
- {
- ***************
- *** 9588,9591 ****
- --- 9597,9614 ----
- }
-
- + if (current_class_type != NULL_TREE)
- + {
- + /* class local enum declaration */
- + decl = build_lang_field_decl (CONST_DECL, name, integer_type_node);
- + DECL_INITIAL (decl) = value;
- + TREE_READONLY (decl) = 1;
- + pushdecl_class_level (decl);
- +
- + /* chain the decl in the tree classlocal_enum_decls
- + See grok_enum_decls () where it is used and reset. */
- + TREE_CHAIN (decl) = classlocal_enum_decls;
- + classlocal_enum_decls = decl;
- + }
- +
- /* Set basis for default for next value. */
- enum_next_value = build_binary_op_nodefault (PLUS_EXPR, value,
- ***************
- *** 9601,9634 ****
- tree type, decl;
- {
- ! struct binding_level *b = class_binding_level;
- ! tree tag = NULL_TREE;
- ! tree values;
-
- ! while (b)
- ! {
- ! tag = value_member (type, b->tags);
- ! if (tag)
- ! break;
- ! b = b->level_chain;
- ! }
-
- ! if (b == 0 || (b != class_binding_level) || TREE_ADDRESSABLE (tag))
- return decl;
- ! else
- ! TREE_ADDRESSABLE (tag) = 1;
- !
- ! values = TYPE_VALUES (type);
- ! while (values)
- {
- ! /* Create a declaration for the enum value name. */
- ! tree next = build_lang_field_decl (CONST_DECL, TREE_PURPOSE (values), type);
- ! TREE_READONLY (next) = 1;
- ! DECL_INITIAL (next) = TREE_VALUE (values);
- ! TREE_CHAIN (next) = decl;
- ! decl = next;
- ! pushdecl_class_level (decl);
- ! values = TREE_CHAIN (values);
- }
- ! return decl;
- }
-
- --- 9624,9646 ----
- tree type, decl;
- {
- ! tree d, ret;
-
- ! d = ret = classlocal_enum_decls;
- ! classlocal_enum_decls = NULL_TREE;
-
- ! if (d == 0)
- return decl;
- !
- ! for (;;)
- {
- ! TREE_TYPE (d) = type;
- ! if (TREE_CHAIN (d) == NULL_TREE)
- ! {
- ! TREE_CHAIN (d) = decl;
- ! break;
- ! }
- ! d = TREE_CHAIN (d);
- }
- ! return ret;
- }
-
-
-