Article View: gnu.g++.bug
Article #1195Fix for class local enum bug
From: Gnanasekaran Swaminathan
Date: Wed, 30 Dec 1992 17:57
Date: Wed, 30 Dec 1992 17:57
149 lines
4594 bytes
4594 bytes
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;
}
Technical Details
Message-ID:
<9212310357.AA48953@kelvin.seas.Virginia.EDU>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!kelvin.seas.virginia.edu!gs4tShow Full Headers
Complete Article Headers
Newsgroups: gnu.g++.bug Path: arc1-ca.pugleaf.net!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