OSDN Git Service

78th Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 17 Jan 1996 18:57:55 +0000 (18:57 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 17 Jan 1996 18:57:55 +0000 (18:57 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11039 138bc75d-0d04-0410-961f-82ee72b054a4

19 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/gxxint.texi
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/sig.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index a1722c2..22cb2b3 100644 (file)
@@ -1,3 +1,137 @@
+Wed Jan 17 10:18:01 1996  Mike Stump  <mrs@cygnus.com>
+
+       * decl2.c (warn_pointer_arith): Default to on.
+
+Tue Jan 16 12:45:38 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * lex.c (is_rid): New function.
+       * decl.c (grokdeclarator): Diagnose reserved words used as
+       declarator-ids.
+
+Tue Jan 16 11:39:40 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * tree.c (get_decl_list): Don't lose cv-quals.
+
+       * decl.c (grokdeclarator): Fix SCOPE_REF handling and diagnose
+       typespecs used as declarator-ids.
+
+Tue Jan 16 11:09:42 1996  Mike Stump  <mrs@cygnus.com>
+
+       * decl.c (poplevel): When poping a level, don't give a warning for
+       any subblocks that already exist.
+
+Tue Jan 16 00:25:33 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck.c (build_object_ref): Finish what I started.
+
+       * parse.y (qualified_type_name): Don't check TYPE_BUILT_IN.
+
+       * decl2.c (constructor_name_full): Handle TEMPLATE_TYPE_PARMs.
+
+       * decl.c (grokdeclarator): Also accept TEMPLATE_TYPE_PARM as a
+       scope.
+
+Mon Jan 15 16:19:32 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (xref_tag): Handle passing a type in directly.
+
+       * parse.y (qualified_type_name): Pull out the type.
+       (nested_type): Ditto.
+       Take types directly instead of as identifiers.
+       * call.c (build_scoped_method_call): Take types directly instead of
+       as identifiers.
+       * decl.c (xref_basetypes): Ditto.
+       * init.c (expand_member_init): Ditto.
+       (build_member_call): Ditto.
+       (build_offset_ref): Ditto.
+       * typeck2.c (build_scoped_ref): Ditto, remove bogus code.
+       * method.c (do_build_assign_ref): Ditto.
+       * decl.c (grokdeclarator): Handle a type appearing as the
+       declarator-id for constructors.
+       * method.c (do_build_copy_constructor): current_base_init_list now
+       uses the types directly, not their names.
+       * init.c (sort_base_init): Ditto.
+       (expand_member_init): Ditto.
+       * init.c (is_aggr_type): New function, like is_aggr_typedef.
+       * class.c (pushclass): If !modify and
+       CLASSTYPE_LOCAL_TYPEDECLS (type)), do set up IDENTIFIER_TYPE_VALUE
+       for inherited types.
+
+Mon Jan 15 08:45:01 1996  Jeffrey A Law  (law@cygnus.com)
+
+       * tree.c (layout_basetypes): Call build_lang_field_decl instead
+       of build_lang_decl if first arg is a FIELD_DECL.
+       (tree_copy_lang_decl_for_deferred_output): Reverse test for when
+       to copy DECL_MAIN_VARIANT and DECL_CHAIN.
+
+Thu Jan 11 14:55:07 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * decl.c (cp_finish_decl): Only clear TREE_USED if DECL_NAME is
+       non-empty.
+       * except.c (expand_start_catch_block): Set TREE_USED to avoid
+       warnings about the catch handler.
+
+Mon Jan  8 17:35:12 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck.c (build_modify_expr): Use a COMPOUND_EXPR instead of
+       expand_target_expr.
+
+Thu Jan  4 12:30:32 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       Fix access control to use trees rather than integers.
+       * class.c (access_{default, public, protected, private,
+       default_virtual, public_virtual, private_virtual}_node): Add
+       definitions.
+       (init_class_processing): Do creation of those nodes.
+       * cp-tree.h (access_type): Delete enum decl.
+       (access_{default, public, protected, private, default_virtual,
+       public_virtual, private_virtual}_node): Add decls.
+       (compute_access): Change return type.
+       * search.c (compute_access): Have tree return type, instead of enum.
+       (lookup_field): Declare THIS_V and NEW_V to be tree nodes.
+       * lex.c (real_yylex): Use yylval.ttype for giving the value of the
+       access_* node for each of RID_{PUBLIC, PRIVATE, PROTECTED}.
+       * parse.y (VISSPEC): Make ttype rather than itype.
+       (base_class_access_list): Likewise.
+       * *.[cy]: Change all refs of `access_public' to `access_public_node',
+       etc.
+       * call.c (build_method_call): Make ACCESS be a tree.
+       * class.c (alter_access, finish_struct_1, filter_struct): Likewise.
+       * cvt.c (convert_to_aggr): Likewise.
+       * init.c (build_offset_ref, resolve_offset_ref, build_delete):
+       Likewise.
+       * method.c (hack_identifier): Likewise.
+       * typeck.c (build_component_ref_1, build_component_ref): ): Likewise.
+
+Thu Jan  4 11:02:20 1996  Mike Stump  <mrs@cygnus.com>
+
+       * typeck.c (pointer_int_sum, pointer_diff): Make code agree with C
+       frontend, and make it more consistent with respect to
+       warn_pointer_arith.
+
+Tue Jan  2 00:13:38 1996  Rusty Russell  <rusty@adelaide.maptek.com.au>
+
+       * decl.c (pushdecl): Check for duplicate parameter names.
+
+Wed Jan  3 09:25:48 1996  Mike Stump  <mrs@cygnus.com>
+
+       * decl.c (expand_static_init): Call assemble_external for atexit.
+
+Wed Jan  3 07:55:19 1996  Mike Stump  <mrs@cygnus.com>
+
+       * except.c (do_unwind): Remove some generated dead code.
+       (eh_outer_context): New routine, factor out some common code from
+       expand_builtin_throw and end_eh_unwinder.  Add code to do return
+       address masking for the PA.
+       (expand_builtin_throw): Use eh_outer_context instead of open coding
+       it here.
+       (end_eh_unwinder): Ditto.
+
+Tue Jan  2 17:00:56 1996  Mike Stump  <mrs@cygnus.com>
+
+       * except.c (expand_throw): Call assemble_external for __empty, if we
+       use it.
+
 Thu Dec 28 11:13:15 1995  Mike Stump  <mrs@cygnus.com>
 
        * except.c (expand_builtin_throw): Use RETURN_ADDR_OFFSET instead of
@@ -3977,7 +4111,7 @@ Fri Dec  9 18:17:37 1994  Doug Evans  <dje@cygnus.com>
        (PARSE_H): Depend on $(PARSE_C), for parallel makes.
        (PARSE_C): Undo last patch.
 
-Fri Dec  2 10:44:36 1994  Mike Stump  (mrs@wombat.gnu.ai.mit.edu)
+Fri Dec  2 10:44:36 1994  Mike Stump  <mrs@cygnus.com>
 
        * Makefile.in (BISONFLAGS): Add --yacc so that output winds up in
        y.tab.c.
index 973deaa..cbe5588 100644 (file)
@@ -1461,8 +1461,8 @@ resolve_scope_to_name (outer_type, inner_stuff)
 /* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'.
    This is how virtual function calls are avoided.  */
 tree
-build_scoped_method_call (exp, scopes, name, parms)
-     tree exp, scopes, name, parms;
+build_scoped_method_call (exp, basetype, name, parms)
+     tree exp, basetype, name, parms;
 {
   /* Because this syntactic form does not allow
      a pointer to a base class to be `stolen',
@@ -1470,23 +1470,20 @@ build_scoped_method_call (exp, scopes, name, parms)
      that happens here.
      
      @@ But we do have to check access privileges later.  */
-  tree basename = resolve_scope_to_name (NULL_TREE, scopes);
-  tree basetype, binfo, decl;
+  tree binfo, decl;
   tree type = TREE_TYPE (exp);
 
   if (type == error_mark_node
-      || basename == NULL_TREE)
+      || basetype == error_mark_node)
     return error_mark_node;
 
-  basetype = IDENTIFIER_TYPE_VALUE (basename);
-
   if (TREE_CODE (type) == REFERENCE_TYPE)
     type = TREE_TYPE (type);
 
   /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
      that explicit ~int is caught in the parser; this deals with typedefs
      and template parms.  */
-  if (TREE_CODE (name) == BIT_NOT_EXPR && ! is_aggr_typedef (basename, 0))
+  if (TREE_CODE (name) == BIT_NOT_EXPR && ! IS_AGGR_TYPE (basetype))
     {
       if (type != basetype)
        cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
@@ -1498,7 +1495,7 @@ build_scoped_method_call (exp, scopes, name, parms)
       return convert (void_type_node, exp);
     }
 
-  if (! is_aggr_typedef (basename, 1))
+  if (! is_aggr_type (basetype, 1))
     return error_mark_node;
 
   if (! IS_AGGR_TYPE (type))
@@ -1516,7 +1513,7 @@ build_scoped_method_call (exp, scopes, name, parms)
        decl = build_indirect_ref (convert_pointer_to (binfo,
                                                       build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
       else
-       decl = build_scoped_ref (exp, scopes);
+       decl = build_scoped_ref (exp, basetype);
 
       /* Call to a destructor.  */
       if (TREE_CODE (name) == BIT_NOT_EXPR)
@@ -1613,7 +1610,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
   register tree baselink, result, method_name, parmtypes, parm;
   tree last;
   int pass;
-  enum access_type access = access_public;
+  tree access = access_public_node;
 
   /* Range of cases for vtable optimization.  */
   enum vtable_needs { not_needed, maybe_needed, unneeded, needed };
@@ -2422,7 +2419,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
   if (flags & LOOKUP_PROTECT)
     access = compute_access (basetype_path, function);
 
-  if (access == access_private)
+  if (access == access_private_node)
     {
       if (flags & LOOKUP_COMPLAIN)
        {
@@ -2433,7 +2430,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
        }
       return error_mark_node;
     }
-  else if (access == access_protected)
+  else if (access == access_protected_node)
     {
       if (flags & LOOKUP_COMPLAIN)
        {
index fc25b1a..cca35da 100644 (file)
@@ -98,6 +98,15 @@ char *dont_allow_type_definitions;
    via this node.  */
 static tree base_layout_decl;
 
+/* Constants used for access control.  */
+tree access_default_node; /* 0 */
+tree access_public_node; /* 1 */
+tree access_protected_node; /* 2 */
+tree access_private_node; /* 3 */
+tree access_default_virtual_node; /* 4 */
+tree access_public_virtual_node; /* 5 */
+tree access_private_virtual_node; /* 6 */
+
 /* Variables shared between class.c and call.c.  */
 
 int n_vtables = 0;
@@ -1108,10 +1117,10 @@ static int
 alter_access (t, fdecl, access)
      tree t;
      tree fdecl;
-     enum access_type access;
+     tree access;
 {
   tree elem = purpose_member (t, DECL_ACCESS (fdecl));
-  if (elem && TREE_VALUE (elem) != (tree)access)
+  if (elem && TREE_VALUE (elem) != access)
     {
       if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
        {
@@ -1123,25 +1132,24 @@ alter_access (t, fdecl, access)
     }
   else if (TREE_PRIVATE (fdecl))
     {
-      if (access != access_private)
+      if (access != access_private_node)
        cp_error_at ("cannot make private `%D' non-private", fdecl);
       goto alter;
     }
   else if (TREE_PROTECTED (fdecl))
     {
-      if (access != access_protected)
+      if (access != access_protected_node)
        cp_error_at ("cannot make protected `%D' non-protected", fdecl);
       goto alter;
     }
   /* ARM 11.3: an access declaration may not be used to restrict access
      to a member that is accessible in the base class.  */
-  else if (access != access_public)
+  else if (access != access_public_node)
     cp_error_at ("cannot reduce access of public member `%D'", fdecl);
   else if (elem == NULL_TREE)
     {
     alter:
-      DECL_ACCESS (fdecl) = tree_cons (t, (tree)access,
-                                          DECL_ACCESS (fdecl));
+      DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
       return 1;
     }
   return 0;
@@ -2957,16 +2965,16 @@ finish_struct_1 (t, warn_anon)
       if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
        {
          tree fdecl = TREE_OPERAND (DECL_NAME (x), 1);
-         enum access_type access
-           = TREE_PRIVATE (x) ? access_private :
-             TREE_PROTECTED (x) ? access_protected : access_public;
+         tree access
+           = TREE_PRIVATE (x) ? access_private_node :
+             TREE_PROTECTED (x) ? access_protected_node : access_public_node;
 
          if (last_x)
            TREE_CHAIN (last_x) = TREE_CHAIN (x);
          else
            fields = TREE_CHAIN (x);
 
-         access_decls = tree_cons ((tree) access, fdecl, access_decls);
+         access_decls = tree_cons (access, fdecl, access_decls);
          continue;
        }
 
@@ -3411,7 +3419,7 @@ finish_struct_1 (t, warn_anon)
        tree fdecl = TREE_VALUE (access_decls);
        tree flist = NULL_TREE;
        tree name;
-       enum access_type access = (enum access_type)TREE_PURPOSE(access_decls);
+       tree access = TREE_PURPOSE(access_decls);
        int i = TREE_VEC_ELT (method_vec, 0) ? 0 : 1;
        tree tmp;
 
@@ -4053,7 +4061,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
   tree *tail = &TYPE_METHODS (t);
   tree name = TYPE_NAME (t);
   tree x, last_x = NULL_TREE;
-  enum access_type access;
+  tree access;
 
   if (TREE_CODE (name) == TYPE_DECL)
     {
@@ -4083,21 +4091,21 @@ finish_struct (t, list_of_fieldlists, warn_anon)
   if (CLASSTYPE_DECLARED_CLASS (t) == 0)
     {
       if (list_of_fieldlists
-         && TREE_PURPOSE (list_of_fieldlists) == (tree)access_default)
-       TREE_PURPOSE (list_of_fieldlists) = (tree)access_public;
+         && TREE_PURPOSE (list_of_fieldlists) == access_default_node)
+       TREE_PURPOSE (list_of_fieldlists) = access_public_node;
     }
   else if (list_of_fieldlists
-          && TREE_PURPOSE (list_of_fieldlists) == (tree)access_default)
-    TREE_PURPOSE (list_of_fieldlists) = (tree)access_private;
+          && TREE_PURPOSE (list_of_fieldlists) == access_default_node)
+    TREE_PURPOSE (list_of_fieldlists) = access_private_node;
 
   while (list_of_fieldlists)
     {
-      access = (enum access_type)TREE_PURPOSE (list_of_fieldlists);
+      access = TREE_PURPOSE (list_of_fieldlists);
 
       for (x = TREE_VALUE (list_of_fieldlists); x; x = TREE_CHAIN (x))
        {
-         TREE_PRIVATE (x) = access == access_private;
-         TREE_PROTECTED (x) = access == access_protected;
+         TREE_PRIVATE (x) = access == access_private_node;
+         TREE_PROTECTED (x) = access == access_protected_node;
 
          /* Check for inconsistent use of this name in the class body.
              Enums, types and static vars have already been checked.  */
@@ -4306,6 +4314,14 @@ init_class_processing ()
   current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree));
   current_lang_stack = current_lang_base;
 
+  access_default_node = build_int_2 (0, 0);
+  access_public_node = build_int_2 (1, 0);
+  access_protected_node = build_int_2 (2, 0);
+  access_private_node = build_int_2 (3, 0);
+  access_default_virtual_node = build_int_2 (4, 0);
+  access_public_virtual_node = build_int_2 (5, 0);
+  access_private_virtual_node = build_int_2 (6, 0);
+
   /* Keep these values lying around.  */
   the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node);
   base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node);
@@ -4400,7 +4416,7 @@ pushclass (type, modify)
       else if (type != previous_class_type || current_class_depth > 1)
        {
          build_mi_matrix (type);
-         push_class_decls (type);
+         push_class_decls (type, !modify);
          free_mi_matrix ();
          if (current_class_depth == 1)
            previous_class_type = type;
@@ -4437,6 +4453,12 @@ pushclass (type, modify)
 
       current_function_decl = this_fndecl;
     }
+  else if (CLASSTYPE_LOCAL_TYPEDECLS (type))
+    {
+      build_mi_matrix (type);
+      push_class_decls (type, !modify);
+      free_mi_matrix ();
+    }
 
   if (flag_cadillac)
     cadillac_push_class (type);
index ddea575..6ad5ea0 100644 (file)
@@ -1727,15 +1727,14 @@ extern int current_function_parms_stored;
    can have.  These are sensible combinations of {public,private,protected}
    cross {virtual,non-virtual}.  */
 
-enum access_type {
-  access_default,
-  access_public,
-  access_protected,
-  access_private,
-  access_default_virtual,
-  access_public_virtual,
-  access_private_virtual
-};
+/* in class.c. */
+extern tree access_default_node; /* 0 */
+extern tree access_public_node; /* 1 */
+extern tree access_protected_node; /* 2 */
+extern tree access_private_node; /* 3 */
+extern tree access_default_virtual_node; /* 4 */
+extern tree access_public_virtual_node; /* 5 */
+extern tree access_private_virtual_node; /* 6 */
 
 /* in lex.c  */
 extern tree current_unit_name, current_unit_language;
@@ -2311,7 +2310,7 @@ extern void push_memoized_context         PROTO((tree, int));
 extern void pop_memoized_context               PROTO((int));
 extern tree get_binfo                          PROTO((tree, tree, int));
 extern int get_base_distance                   PROTO((tree, tree, int, tree *));
-extern enum access_type compute_access         PROTO((tree, tree));
+extern tree compute_access                     PROTO((tree, tree));
 extern tree lookup_field                       PROTO((tree, tree, int, int));
 extern tree lookup_nested_field                        PROTO((tree, int));
 extern tree lookup_fnfields                    PROTO((tree, tree, int));
@@ -2333,7 +2332,7 @@ extern void build_mi_virtuals                     PROTO((int, int));
 extern void add_mi_virtuals                    PROTO((int, tree));
 extern void report_ambiguous_mi_virtuals       PROTO((int, tree));
 extern void note_debug_info_needed             PROTO((tree));
-extern void push_class_decls                   PROTO((tree));
+extern void push_class_decls                   PROTO((tree, int));
 extern void pop_class_decls                    PROTO((tree));
 extern void unuse_fields                       PROTO((tree));
 extern void unmark_finished_struct             PROTO((tree));
index a4e28ff..c135bba 100644 (file)
@@ -896,8 +896,7 @@ convert_to_aggr (type, expr, msgp, protect)
   tree basetype = type;
   tree name = TYPE_IDENTIFIER (basetype);
   tree function, fndecl, fntype, parmtypes, parmlist, result;
-  tree method_name;
-  enum access_type access;
+  tree method_name, access;
   int can_be_private, can_be_protected;
 
   if (! TYPE_HAS_CONSTRUCTOR (basetype))
@@ -907,7 +906,7 @@ convert_to_aggr (type, expr, msgp, protect)
       return error_mark_node;
     }
 
-  access = access_public;
+  access = access_public_node;
   can_be_private = 0;
   can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name;
 
@@ -987,20 +986,20 @@ convert_to_aggr (type, expr, msgp, protect)
            if (protect)
              {
                if (TREE_PRIVATE (fndecl))
-                 access = access_private;
+                 access = access_private_node;
                else if (TREE_PROTECTED (fndecl))
-                 access = access_protected;
+                 access = access_protected_node;
                else
-                 access = access_public;
+                 access = access_public_node;
              }
            else
-             access = access_public;
+             access = access_public_node;
 
-           if (access == access_private
+           if (access == access_private_node
                ? (basetype == current_class_type
                   || is_friend (basetype, cp->function)
                   || purpose_member (basetype, DECL_ACCESS (fndecl)))
-               : access == access_protected
+               : access == access_protected_node
                ? (can_be_protected
                   || purpose_member (basetype, DECL_ACCESS (fndecl)))
                : 1)
@@ -1011,7 +1010,7 @@ convert_to_aggr (type, expr, msgp, protect)
              }
            else
              {
-               if (access == access_private)
+               if (access == access_private_node)
                  saw_private = 1;
                else
                  saw_protected = 1;
@@ -1061,7 +1060,7 @@ convert_to_aggr (type, expr, msgp, protect)
   /* NOTREACHED */
 
  found:
-  if (access == access_private)
+  if (access == access_private_node)
     if (! can_be_private)
       {
        if (msgp)
@@ -1070,7 +1069,7 @@ convert_to_aggr (type, expr, msgp, protect)
            : "conversion to type `%s' is from private base class";
        return error_mark_node;
       }
-  if (access == access_protected)
+  if (access == access_protected_node)
     if (! can_be_protected)
       {
        if (msgp)
index 869d853..49eb67e 100644 (file)
@@ -1104,17 +1104,22 @@ poplevel (keep, reverse, functionbody)
        {
          if (decls || tags || subblocks)
            {
-             if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block) || BLOCK_SUBBLOCKS (block))
+             if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block))
                {
                  warning ("internal compiler error: debugging info corrupted");
                }
              BLOCK_VARS (block) = decls;
              BLOCK_TYPE_TAGS (block) = tags;
-             /* Recover from too many blocks by chaining them together. */
-             BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block), subblocks);
+
+             /* We can have previous subblocks and new subblocks when
+                doing fixup_gotos with complex cleanups.  We chain the new
+                subblocks onto the end of any pre-existing subblocks.  */
+             BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block),
+                                                subblocks);
            }
-         /* If we created the block earlier on, and we are just diddling it now, then
-            it already should have a proper BLOCK_END_NOTE value associated with it.  */
+         /* If we created the block earlier on, and we are just
+            diddling it now, then it already should have a proper
+            BLOCK_END_NOTE value associated with it.  */
        }
       else
        {
@@ -3140,6 +3145,10 @@ pushdecl (x)
            {
              if (DECL_CONTEXT (t) == NULL_TREE)
                fatal ("parse errors have confused me too much");
+
+             /* Check for duplicate params. */
+             if (duplicate_decls (x, t))
+               return t;
            }
          else if (((TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c)
               || (TREE_CODE (x) == TEMPLATE_DECL
@@ -6909,7 +6918,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
                 was initialized was ever used.  Don't do this if it has a
                 destructor, so we don't complain about the 'resource
                 allocation is initialization' idiom.  */
-             if (TYPE_NEEDS_CONSTRUCTING (type) && cleanup == NULL_TREE)
+             if (TYPE_NEEDS_CONSTRUCTING (type)
+                 && cleanup == NULL_TREE
+                 && DECL_NAME (decl))
                TREE_USED (decl) = 0;
 
              /* Store the cleanup, if there was one.  */
@@ -7069,6 +7080,7 @@ expand_static_init (decl, init)
                                  build_function_type (void_type_node,
                                                       pfvlist),
                                  NOT_BUILT_IN, NULL_PTR);
+             assemble_external (atexit_fndecl);
              Atexit = default_conversion (atexit_fndecl);
              pop_lang_context ();
              pop_obstacks ();
@@ -7690,222 +7702,211 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
   /* Look inside a declarator for the name being declared
      and get it as a string, for an error message.  */
   {
-    tree last = NULL_TREE;
-    register tree decl = declarator;
+    tree *next = &declarator;
+    register tree decl;
     name = NULL;
 
-    while (decl)
-      switch (TREE_CODE (decl))
-        {
-       case COND_EXPR:
-         ctype = NULL_TREE;
-         decl = TREE_OPERAND (decl, 0);
-         break;
-
-       case BIT_NOT_EXPR:      /* for C++ destructors!  */
+    while (next && *next)
+      {
+       decl = *next;
+       switch (TREE_CODE (decl))
          {
-           tree name = TREE_OPERAND (decl, 0);
-           tree rename = NULL_TREE;
-
-           my_friendly_assert (flags == NO_SPECIAL, 152);
-           flags = DTOR_FLAG;
-           return_type = return_dtor;
-           my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
-           if (ctype == NULL_TREE)
-             {
-               if (current_class_type == NULL_TREE)
-                 {
-                   error ("destructors must be member functions");
-                   flags = NO_SPECIAL;
-                 }
-               else
-                 {
-                   tree t = constructor_name (current_class_name);
-                   if (t != name)
-                     rename = t;
-                 }
-             }
-           else
-             {
-               tree t = constructor_name (ctype);
-               if (t != name)
-                 rename = t;
-             }
-
-           if (rename)
-             {
-               error ("destructor `%s' must match class name `%s'",
-                      IDENTIFIER_POINTER (name),
-                      IDENTIFIER_POINTER (rename));
-               TREE_OPERAND (decl, 0) = rename;
-             }
-           decl = name;
-         }
-         break;
-
-       case ADDR_EXPR:         /* C++ reference declaration */
-         /* fall through */
-       case ARRAY_REF:
-       case INDIRECT_REF:
-         ctype = NULL_TREE;
-         innermost_code = TREE_CODE (decl);
-         last = decl;
-         decl = TREE_OPERAND (decl, 0);
-         break;
+         case COND_EXPR:
+           ctype = NULL_TREE;
+           next = &TREE_OPERAND (decl, 0);
+           break;
 
-       case CALL_EXPR:
-         if (parmlist_is_exprlist (TREE_OPERAND (decl, 1)))
+         case BIT_NOT_EXPR:    /* for C++ destructors!  */
            {
-             /* This is actually a variable declaration using constructor
-                syntax.  We need to call start_decl and cp_finish_decl so we
-                can get the variable initialized...  */
-
-             if (last)
-               /* We need to insinuate ourselves into the declarator in place
-                  of the CALL_EXPR.  */
-               TREE_OPERAND (last, 0) = TREE_OPERAND (decl, 0);
+             tree name = TREE_OPERAND (decl, 0);
+             tree rename = NULL_TREE;
+
+             my_friendly_assert (flags == NO_SPECIAL, 152);
+             flags = DTOR_FLAG;
+             return_type = return_dtor;
+             my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
+             if (ctype == NULL_TREE)
+               {
+                 if (current_class_type == NULL_TREE)
+                   {
+                     error ("destructors must be member functions");
+                     flags = NO_SPECIAL;
+                   }
+                 else
+                   {
+                     tree t = constructor_name (current_class_name);
+                     if (t != name)
+                       rename = t;
+                   }
+               }
              else
-               declarator = TREE_OPERAND (decl, 0);
-
-             init = TREE_OPERAND (decl, 1);
-
-             decl = start_decl (declarator, declspecs, 1, NULL_TREE);
-             finish_decl (decl, init, NULL_TREE);
-             return 0;
-           }
-         innermost_code = TREE_CODE (decl);
-         if (decl_context == FIELD && ctype == NULL_TREE)
-           ctype = current_class_type;
-         if (ctype
-             && TREE_OPERAND (decl, 0) == constructor_name_full (ctype))
-           TREE_OPERAND (decl, 0) = constructor_name (ctype);
-         decl = TREE_OPERAND (decl, 0);
-         if (ctype != NULL_TREE
-             && decl != NULL_TREE && flags != DTOR_FLAG
-             && decl == constructor_name (ctype))
-           {
-             return_type = return_ctor;
-             ctor_return_type = ctype;
-           }
-         ctype = NULL_TREE;
-         break;
-
-       case IDENTIFIER_NODE:
-         dname = decl;
-         decl = NULL_TREE;
+               {
+                 tree t = constructor_name (ctype);
+                 if (t != name)
+                   rename = t;
+               }
 
-         if (! IDENTIFIER_OPNAME_P (dname)
-             /* Linux headers use '__op'.  Arrgh.  */
-             || IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname))
-           name = IDENTIFIER_POINTER (dname);
-         else
-           {
-             if (IDENTIFIER_TYPENAME_P (dname))
+             if (rename)
                {
-                 my_friendly_assert (flags == NO_SPECIAL, 154);
-                 flags = TYPENAME_FLAG;
-                 ctor_return_type = TREE_TYPE (dname);
-                 return_type = return_conversion;
+                 error ("destructor `%s' must match class name `%s'",
+                        IDENTIFIER_POINTER (name),
+                        IDENTIFIER_POINTER (rename));
+                 TREE_OPERAND (decl, 0) = rename;
                }
-             name = operator_name_string (dname);
+             next = &name;
            }
-         break;
+           break;
 
-       case RECORD_TYPE:
-       case UNION_TYPE:
-       case ENUMERAL_TYPE:
-         /* Parse error puts this typespec where
-            a declarator should go.  */
-         error ("declarator name missing");
-         dname = TYPE_NAME (decl);
-         if (dname && TREE_CODE (dname) == TYPE_DECL)
-           dname = DECL_NAME (dname);
-         name = dname ? IDENTIFIER_POINTER (dname) : "<nameless>";
-         declspecs = temp_tree_cons (NULL_TREE, decl, declspecs);
-         decl = NULL_TREE;
-         break;
+         case ADDR_EXPR:       /* C++ reference declaration */
+           /* fall through */
+         case ARRAY_REF:
+         case INDIRECT_REF:
+           ctype = NULL_TREE;
+           innermost_code = TREE_CODE (decl);
+           next = &TREE_OPERAND (decl, 0);
+           break;
 
-         /* C++ extension */
-       case SCOPE_REF:
-         {
-           /* Perform error checking, and convert class names to types.
-              We may call grokdeclarator multiple times for the same
-              tree structure, so only do the conversion once.  In this
-              case, we have exactly what we want for `ctype'.  */
-           tree cname = TREE_OPERAND (decl, 0);
-           if (cname == NULL_TREE)
-             ctype = NULL_TREE;
-           /* Can't use IS_AGGR_TYPE because CNAME might not be a type.  */
-           else if (IS_AGGR_TYPE_CODE (TREE_CODE (cname))
-                    || TREE_CODE (cname) == UNINSTANTIATED_P_TYPE)
-             ctype = cname;
-           else if (! is_aggr_typedef (cname, 1))
+         case CALL_EXPR:
+           if (parmlist_is_exprlist (TREE_OPERAND (decl, 1)))
              {
-               TREE_OPERAND (decl, 0) = NULL_TREE;
+               /* This is actually a variable declaration using constructor
+                  syntax.  We need to call start_decl and cp_finish_decl so we
+                  can get the variable initialized...  */
+
+               *next = TREE_OPERAND (decl, 0);
+               init = TREE_OPERAND (decl, 1);
+
+               decl = start_decl (declarator, declspecs, 1, NULL_TREE);
+               finish_decl (decl, init, NULL_TREE);
+               return 0;
              }
-           /* Must test TREE_OPERAND (decl, 1), in case user gives
-              us `typedef (class::memfunc)(int); memfunc *memfuncptr;'  */
-           else if (TREE_OPERAND (decl, 1)
-                    && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)
+           innermost_code = TREE_CODE (decl);
+           if (decl_context == FIELD && ctype == NULL_TREE)
+             ctype = current_class_type;
+           if (ctype && TREE_OPERAND (decl, 0) == ctype)
+             TREE_OPERAND (decl, 0) = constructor_name (ctype);
+           next = &TREE_OPERAND (decl, 0);
+           decl = *next;
+           if (ctype != NULL_TREE
+               && decl != NULL_TREE && flags != DTOR_FLAG
+               && decl == constructor_name (ctype))
              {
-               TREE_OPERAND (decl, 0) = IDENTIFIER_TYPE_VALUE (cname);
+               return_type = return_ctor;
+               ctor_return_type = ctype;
              }
-           else if (ctype == NULL_TREE)
+           ctype = NULL_TREE;
+           break;
+
+         case IDENTIFIER_NODE:
+           dname = decl;
+           next = 0;
+
+           if (is_rid (dname))
              {
-               ctype = IDENTIFIER_TYPE_VALUE (cname);
-               TREE_OPERAND (decl, 0) = ctype;
+               cp_error ("declarator-id missing; using reserved word `%D'",
+                         dname);
+               name = IDENTIFIER_POINTER (dname);
              }
-           else if (TREE_COMPLEXITY (decl) == current_class_depth)
-             TREE_OPERAND (decl, 0) = ctype;
+           if (! IDENTIFIER_OPNAME_P (dname)
+               /* Linux headers use '__op'.  Arrgh.  */
+               || IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname))
+             name = IDENTIFIER_POINTER (dname);
            else
              {
-               if (! UNIQUELY_DERIVED_FROM_P (IDENTIFIER_TYPE_VALUE (cname),
-                                              ctype))
+               if (IDENTIFIER_TYPENAME_P (dname))
                  {
-                   cp_error ("type `%T' is not derived from type `%T'",
-                             IDENTIFIER_TYPE_VALUE (cname), ctype);
-                   TREE_OPERAND (decl, 0) = NULL_TREE;
-                 }
-               else
-                 {
-                   ctype = IDENTIFIER_TYPE_VALUE (cname);
-                   TREE_OPERAND (decl, 0) = ctype;
+                   my_friendly_assert (flags == NO_SPECIAL, 154);
+                   flags = TYPENAME_FLAG;
+                   ctor_return_type = TREE_TYPE (dname);
+                   return_type = return_conversion;
                  }
+               name = operator_name_string (dname);
              }
+           break;
 
-           if (ctype
-               && TREE_OPERAND (decl, 1) == constructor_name_full (ctype))
-             TREE_OPERAND (decl, 1) = constructor_name (ctype);
-           decl = TREE_OPERAND (decl, 1);
-           if (ctype)
+           /* C++ extension */
+         case SCOPE_REF:
+           {
+             /* Perform error checking, and decide on a ctype.  */
+             tree cname = TREE_OPERAND (decl, 0);
+             if (cname == NULL_TREE)
+               ctype = NULL_TREE;
+             else if (! is_aggr_type (cname, 1))
+               TREE_OPERAND (decl, 0) = NULL_TREE;
+             /* Must test TREE_OPERAND (decl, 1), in case user gives
+                us `typedef (class::memfunc)(int); memfunc *memfuncptr;'  */
+             else if (TREE_OPERAND (decl, 1)
+                      && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)
+               ctype = cname;
+             else if (ctype == NULL_TREE)
+               ctype = cname;
+             else if (TREE_COMPLEXITY (decl) == current_class_depth)
+               TREE_OPERAND (decl, 0) = ctype;
+             else
+               {
+                 if (! UNIQUELY_DERIVED_FROM_P (cname, ctype))
+                   {
+                     cp_error ("type `%T' is not derived from type `%T'",
+                               cname, ctype);
+                     TREE_OPERAND (decl, 0) = NULL_TREE;
+                   }
+                 else
+                   ctype = cname;
+               }
+
+             if (ctype
+                 && TREE_OPERAND (decl, 1) == constructor_name_full (ctype))
+               TREE_OPERAND (decl, 1) = constructor_name (ctype);
+             next = &TREE_OPERAND (decl, 1);
+             decl = *next;
+             if (ctype)
+               {
+                 if (TREE_CODE (decl) == IDENTIFIER_NODE
+                     && constructor_name (ctype) == decl)
+                   {
+                     return_type = return_ctor;
+                     ctor_return_type = ctype;
+                   }
+                 else if (TREE_CODE (decl) == BIT_NOT_EXPR
+                          && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
+                          && (constructor_name (ctype) == TREE_OPERAND (decl, 0)
+                              || constructor_name_full (ctype) == TREE_OPERAND (decl, 0)))
+                   {
+                     return_type = return_dtor;
+                     ctor_return_type = ctype;
+                     flags = DTOR_FLAG;
+                     TREE_OPERAND (decl, 0) = constructor_name (ctype);
+                     next = &TREE_OPERAND (decl, 0);
+                   }
+               }
+           }
+           break;
+
+         case ERROR_MARK:
+           next = 0;
+           break;
+
+         default:
+           if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't')
              {
-               if (TREE_CODE (decl) == IDENTIFIER_NODE
-                   && constructor_name (ctype) == decl)
-                 {
-                   return_type = return_ctor;
-                   ctor_return_type = ctype;
-                 }
-               else if (TREE_CODE (decl) == BIT_NOT_EXPR
-                        && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
-                        && (constructor_name (ctype) == TREE_OPERAND (decl, 0)
-                            || constructor_name_full (ctype) == TREE_OPERAND (decl, 0)))
-                 {
-                   return_type = return_dtor;
-                   ctor_return_type = ctype;
-                   flags = DTOR_FLAG;
-                   decl = TREE_OPERAND (decl, 0) = constructor_name (ctype);
-                 }
+               /* Parse error puts this typespec where
+                  a declarator should go.  */
+               error ("typename specified as declarator-id");
+               if (current_class_type)
+                 cp_error ("  perhaps you want `%T' for a constructor",
+                           current_class_name);
+               dname = TYPE_IDENTIFIER (decl);
+               name = dname ? IDENTIFIER_POINTER (dname) : "<nameless>";
+               declspecs = temp_tree_cons (NULL_TREE, integer_type_node,
+                                           declspecs);
+               *next = dname;
+               next = 0;
+               break;
              }
+           cp_compiler_error ("`%D' as declarator", decl);
+           return 0; /* We used to do a 155 abort here.  */
          }
-         break;
-
-       case ERROR_MARK:
-         decl = NULL_TREE;
-         break;
-
-       default:
-         return 0; /* We used to do a 155 abort here.  */
-       }
+      }
     if (name == NULL)
       name = "type name";
   }
@@ -10587,7 +10588,13 @@ xref_tag (code_type_node, name, binfo, globalize)
 
   /* If a cross reference is requested, look up the type
      already defined for this tag and return it.  */
-  t = IDENTIFIER_TYPE_VALUE (name);
+  if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
+    {
+      t = name;
+      name = TYPE_NESTED_NAME (t);
+    }
+  else
+    t = IDENTIFIER_TYPE_VALUE (name);
   if (t && TREE_CODE (t) != code)
     t = NULL_TREE;
 
@@ -10770,17 +10777,17 @@ xref_basetypes (code_type_node, name, ref, binfo)
     {
       /* The base of a derived struct is public by default.  */
       int via_public
-       = (TREE_PURPOSE (binfo) == (tree)access_public
-          || TREE_PURPOSE (binfo) == (tree)access_public_virtual
+       = (TREE_PURPOSE (binfo) == access_public_node
+          || TREE_PURPOSE (binfo) == access_public_virtual_node
           || (tag_code != class_type
-              && (TREE_PURPOSE (binfo) == (tree)access_default
-                  || TREE_PURPOSE (binfo) == (tree)access_default_virtual)));
-      int via_protected = TREE_PURPOSE (binfo) == (tree)access_protected;
+              && (TREE_PURPOSE (binfo) == access_default_node
+                  || TREE_PURPOSE (binfo) == access_default_virtual_node)));
+      int via_protected = TREE_PURPOSE (binfo) == access_protected_node;
       int via_virtual
-       = (TREE_PURPOSE (binfo) == (tree)access_private_virtual
-          || TREE_PURPOSE (binfo) == (tree)access_public_virtual
-          || TREE_PURPOSE (binfo) == (tree)access_default_virtual);
-      tree basetype = TREE_TYPE (TREE_VALUE (binfo));
+       = (TREE_PURPOSE (binfo) == access_private_virtual_node
+          || TREE_PURPOSE (binfo) == access_public_virtual_node
+          || TREE_PURPOSE (binfo) == access_default_virtual_node);
+      tree basetype = TREE_VALUE (binfo);
       tree base_binfo;
 
       GNU_xref_hier (IDENTIFIER_POINTER (name),
index 117687a..03b8ff9 100644 (file)
@@ -176,7 +176,7 @@ int warn_traditional;
 /* Nonzero means warn about sizeof(function) or addition/subtraction
    of function pointers.  */
 
-int warn_pointer_arith;
+int warn_pointer_arith = 1;
 
 /* Nonzero means warn for non-prototype function decls
    or non-prototyped defs without previous prototype.  */
@@ -2026,7 +2026,9 @@ constructor_name_full (thing)
 {
   if (TREE_CODE (thing) == UNINSTANTIATED_P_TYPE)
     return DECL_NAME (UPT_TEMPLATE (thing));
-  if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
+  else if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM)
+    thing = TYPE_NAME (thing);
+  else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
     {
       if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing))
        thing = DECL_NAME (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0));
index 38fcb35..09aebdb 100644 (file)
@@ -155,7 +155,7 @@ exception_section ()
   if (flag_pic)
     data_section ();
   else
-#if defined(TARGET_POWERPC) /* are we on a __rs6000? */
+#if defined (TARGET_POWERPC) /* are we on a __rs6000? */
     data_section ();
 #else
     readonly_data_section ();
@@ -1012,6 +1012,10 @@ expand_start_catch_block (declspecs, declarator)
          return;
        }
 
+      /* Make sure we mark the catch param as used, otherwise we'll get
+        a warning about an unused ((anonymous)).  */
+      TREE_USED (decl) = 1;
+
       /* Figure out the type that the initializer is. */
       init_type = TREE_TYPE (decl);
       if (TREE_CODE (init_type) != REFERENCE_TYPE
@@ -1167,7 +1171,8 @@ static void
 do_unwind (inner_throw_label)
      rtx inner_throw_label;
 {
-#if defined(SPARC_STACK_ALIGN) /* was sparc */
+#if defined (SPARC_STACK_ALIGN) /* was sparc */
+  /* This doesn't work for the flat model sparc, I bet.  */
   tree fcall;
   tree params;
   rtx return_val_rtx;
@@ -1186,7 +1191,7 @@ do_unwind (inner_throw_label)
   easy_expand_asm ("restore");
   emit_barrier ();
 #endif
-#if defined(ARM_FRAME_RTX)  /* was __arm */
+#if defined (ARM_FRAME_RTX)  /* was __arm */
   if (flag_omit_frame_pointer)
     sorry ("this implementation of exception handling requires a frame pointer");
 
@@ -1195,7 +1200,7 @@ do_unwind (inner_throw_label)
   emit_move_insn (hard_frame_pointer_rtx,
                  gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -12)));
 #endif
-#if defined(TARGET_88000) /* was m88k */
+#if defined (TARGET_88000) /* was m88k */
   rtx temp_frame = frame_pointer_rtx;
 
   temp_frame = memory_address (Pmode, temp_frame);
@@ -1218,17 +1223,18 @@ do_unwind (inner_throw_label)
                                                     (HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
 #endif
 #endif
-#if !defined(TARGET_88000) && !defined(ARM_FRAME_RTX) && !defined(SPARC_STACK_ALIGN)
+#if ! defined (TARGET_88000) && ! defined (ARM_FRAME_RTX) && ! defined (SPARC_STACK_ALIGN)
   tree fcall;
   tree params;
   rtx return_val_rtx;
 
+#if 0
+  /* I would like to do this here, but the move below doesn't seem to work. */
   /* call to  __builtin_return_address () */
   params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
   fcall = build_function_call (BuiltinReturnAddress, params);
   return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0);
-#if 0
-  /* I would like to do this here, but doesn't seem to work. */
+
   emit_move_insn (return_val_rtx, inner_throw_label);
   /* So, for now, just pass throw label to stack unwinder. */
 #endif
@@ -1242,6 +1248,48 @@ do_unwind (inner_throw_label)
 }
 
 
+/* Given the return address, compute the new pc to throw.  This has to
+   work for the current frame of the current function, and the one
+   above it in the case of throw.  */
+rtx
+eh_outer_context (addr)
+     rtx addr;
+{
+#if defined (ARM_FRAME_RTX)  /* was __arm */
+  /* On the ARM, '__builtin_return_address',  must have 4
+     subtracted from it. */
+  emit_insn (gen_add2_insn (addr, GEN_INT (-4)));
+
+  /* If we are generating code for an ARM2/ARM3 machine or for an ARM6
+     in 26 bit mode, the condition codes must be masked out of the
+     return value, or else they will confuse BuiltinReturnAddress.
+     This does not apply to ARM6 and later processors when running in
+     32 bit mode. */
+  if (!TARGET_6)
+    emit_insn (gen_rtx (SET, Pmode,
+                       addr,
+                       gen_rtx (AND, Pmode,
+                                addr, GEN_INT (0x03fffffc))));
+#else
+#if ! defined (SPARC_STACK_ALIGN) /* was sparc */
+#if defined (TARGET_SNAKE)
+  /* On HPPA, the low order two bits hold the priviledge level, so we
+     must get rid of them.  */
+  emit_insn (gen_rtx (SET, Pmode,
+                     addr,
+                     gen_rtx (AND, Pmode,
+                              addr, GEN_INT (0xfffffffc))));
+#endif
+
+  /* On the SPARC, __builtin_return_address is already -8 or -12, no
+     need to subtract any more from it. */
+  addr = plus_constant (addr, -1);
+#endif
+#endif
+
+  return addr;
+}
+
 /* is called from expand_exception_blocks () to generate the code in a function
    to "throw" if anything in the function needs to perform a throw.
 
@@ -1320,8 +1368,9 @@ expand_builtin_throw ()
   emit_label (gotta_rethrow_it);
 
   /* call to  __builtin_return_address () */
-#if defined(ARM_FRAME_RTX)  /* was __arm */
-/* This replaces a 'call' to __builtin_return_address */
+#if defined (ARM_FRAME_RTX)  /* was __arm */
+  /* This should be moved into arm.h:RETURN_ADDR_RTX */
+  /* This replaces a 'call' to __builtin_return_address */
   return_val_rtx = gen_reg_rtx (Pmode);
   emit_move_insn (return_val_rtx, gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4)));
 #else
@@ -1336,28 +1385,10 @@ expand_builtin_throw ()
 
   emit_jump_insn (gen_beq (gotta_call_terminate));
 
-#if defined(ARM_FRAME_RTX)  /* was __arm */
-  /* On the ARM, '__builtin_return_address',  must have 4
-     subtracted from it. */
-  emit_insn (gen_add2_insn (return_val_rtx, GEN_INT (-4)));
+  return_val_rtx = eh_outer_context (return_val_rtx);
 
-  /* If we are generating code for an ARM2/ARM3 machine or for an ARM6 in 26 bit
-     mode, the condition codes must be masked out of the return value, or else
-     they will confuse BuiltinReturnAddress.  This does not apply to ARM6 and
-     later processors when running in 32 bit mode. */
-  if (!TARGET_6)
-    emit_insn (gen_rtx (SET, Pmode, return_val_rtx, gen_rtx (AND, Pmode, return_val_rtx, GEN_INT (0x03fffffc))));
-#else
-#if !defined(SPARC_STACK_ALIGN) /* was sparc */
-  /* On the SPARC, __builtin_return_address is already -8, no need to
-     subtract any more from it. */
-  return_val_rtx = plus_constant (return_val_rtx, -1);
-#endif
-#endif
-
-  /* yes it did */
-  t = build_modify_expr (saved_pc, NOP_EXPR, make_tree (ptr_type_node, return_val_rtx));
-  expand_expr (t, const0_rtx, VOIDmode, 0);
+  /* Yes it did.  */
+  emit_move_insn (DECL_RTL (saved_pc), return_val_rtx);
 
   do_unwind (gen_rtx (LABEL_REF, Pmode, top_of_loop));
   emit_jump (top_of_loop);
@@ -1700,6 +1731,9 @@ expand_throw (exp)
            }
        }
 
+      if (cleanup == empty_fndecl)
+       assemble_external (empty_fndecl);
+       
       e = build_modify_expr (saved_throw_type, NOP_EXPR, throw_type);
       expand_expr (e, const0_rtx, VOIDmode, 0);
 
@@ -1823,11 +1857,9 @@ end_eh_unwinder (end)
   ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
                                        0, hard_frame_pointer_rtx);
   return_val_rtx = copy_to_reg (ret_val);
-#ifdef RETURN_ADDR_OFFSET
-  return_val_rtx = plus_constant (return_val_rtx, RETURN_ADDR_OFFSET-1);
-#else
-  return_val_rtx = plus_constant (return_val_rtx, -1);
-#endif
+
+  return_val_rtx = eh_outer_context (return_val_rtx);
+
   emit_move_insn (DECL_RTL (saved_pc), return_val_rtx);
   
 #ifdef JUMP_TO_THROW
index 015a33c..36c2520 100644 (file)
@@ -1217,24 +1217,25 @@ The below points out some things that work in g++'s exception handling.
 All completely constructed temps and local variables are cleaned up in
 all unwinded scopes.  Completely constructed parts of partially
 constructed objects are cleaned up.  This includes partially built
-arrays.  Exception specifications are now handled.
+arrays.  Exception specifications are now handled.  Thrown objects are
+now cleaned up all the time.
 
 The below points out some flaws in g++'s exception handling, as it now
 stands.
 
 Only exact type matching or reference matching of throw types works when
--fno-rtti is used.  Only works on a SPARC (like Suns), i386, arm and
-rs6000 machines.  Partial support is in for all other machines, but a
-stack unwinder called __unwind_function has to be written, and added to
-libgcc2 for them.  See below for details on __unwind_function.  Don't
-expect exception handling to work right if you optimize, in fact the
-compiler will probably core dump.  RTL_EXPRs for EH cond variables for
-&& and || exprs should probably be wrapped in UNSAVE_EXPRs, and
-RTL_EXPRs tweaked so that they can be unsaved, and the UNSAVE_EXPR code
-should be in the backend, or alternatively, UNSAVE_EXPR should be ripped
-out and exactly one finalization allowed to be expanded by the backend.
-I talked with kenner about this, and we have to allow multiple
-expansions.
+-fno-rtti is used.  Only works on a SPARC (like Suns), i386, arm,
+rs6000, Alpha and mips machines.  Partial support is in for all other
+machines, but a stack unwinder called __unwind_function has to be
+written, and added to libgcc2 for them.  See below for details on
+__unwind_function.  Don't expect exception handling to work right if you
+optimize, in fact the compiler will probably core dump.  RTL_EXPRs for
+EH cond variables for && and || exprs should probably be wrapped in
+UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be unsaved, and the
+UNSAVE_EXPR code should be in the backend, or alternatively, UNSAVE_EXPR
+should be ripped out and exactly one finalization allowed to be expanded
+by the backend.  I talked with kenner about this, and we have to allow
+multiple expansions.
 
 We only do pointer conversions on exception matching a la 15.3 p2 case
 3: `A handler with type T, const T, T&, or const T& is a match for a
@@ -1266,12 +1267,13 @@ build_exception_variant should sort the incoming list, so that it
 implements set compares, not exact list equality.  Type smashing should
 smash exception specifications using set union.
 
-Thrown objects are usually allocated on the heap, in the usual way, but
-they are never deleted.  They should be deleted by the catch clauses.
-If one runs out of heap space, throwing an object will probably never
-work.  This could be relaxed some by passing an __in_chrg parameter to
-track who has control over the exception object.  Thrown objects are not
-allocated on the heap when they are pointer to object types.
+Thrown objects are usually allocated on the heap, in the usual way.  If
+one runs out of heap space, throwing an object will probably never work.
+This could be relaxed some by passing an __in_chrg parameter to track
+who has control over the exception object.  Thrown objects are not
+allocated on the heap when they are pointer to object types.  We should
+extend it so that all small (<4*sizeof(void*)) objects are stored
+directly, instead of allocated on the heap.
 
 When the backend returns a value, it can create new exception regions
 that need protecting.  The new region should rethrow the object in
index 2c795bb..e114414 100644 (file)
@@ -371,10 +371,10 @@ sort_base_init (t, rbase_ptr, vbase_ptr)
   last = tree_cons (NULL_TREE, NULL_TREE, current_base_init_list);
   for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x))
     {
-      tree basename = TREE_PURPOSE (x);
+      tree basetype = TREE_PURPOSE (x);
       tree binfo;
 
-      if (basename == NULL_TREE)
+      if (basetype == NULL_TREE)
        {
          /* Initializer for single base class.  Must not
             use multiple inheritance or this is ambiguous.  */
@@ -393,9 +393,9 @@ sort_base_init (t, rbase_ptr, vbase_ptr)
            }
          binfo = TREE_VEC_ELT (binfos, 0);
        }
-      else if (is_aggr_typedef (basename, 1))
+      else if (is_aggr_type (basetype, 1))
        {
-         binfo = binfo_or_else (IDENTIFIER_TYPE_VALUE (basename), t);
+         binfo = binfo_or_else (basetype, t);
          if (binfo == NULL_TREE)
            continue;
 
@@ -420,8 +420,7 @@ sort_base_init (t, rbase_ptr, vbase_ptr)
              if (i < 0)
                {
                  cp_error ("`%T' is not an immediate base class of `%T'",
-                           IDENTIFIER_TYPE_VALUE (basename),
-                           current_class_type);
+                           basetype, current_class_type);
                  continue;
                }
            }
@@ -931,6 +930,12 @@ expand_member_init (exp, name, init)
 
   type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
 
+  if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
+    {
+      basetype = name;
+      name = TYPE_IDENTIFIER (name);
+    }
+
   if (name == NULL_TREE && IS_AGGR_TYPE (type))
     switch (CLASSTYPE_N_BASECLASSES (type))
       {
@@ -958,7 +963,7 @@ expand_member_init (exp, name, init)
       if (init == void_type_node)
        init = NULL_TREE;
 
-      if (name == NULL_TREE || IDENTIFIER_HAS_TYPE_VALUE (name))
+      if (name == NULL_TREE || basetype)
        {
          tree base_init;
 
@@ -976,7 +981,6 @@ expand_member_init (exp, name, init)
            }
          else
            {
-             basetype = IDENTIFIER_TYPE_VALUE (name);
              if (basetype != type
                  && ! binfo_member (basetype, TYPE_BINFO (type))
                  && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))
@@ -984,32 +988,28 @@ expand_member_init (exp, name, init)
                  if (IDENTIFIER_CLASS_VALUE (name))
                    goto try_member;
                  if (TYPE_USES_VIRTUAL_BASECLASSES (type))
-                   error ("type `%s' is not an immediate or virtual basetype for `%s'",
-                          IDENTIFIER_POINTER (name),
-                          TYPE_NAME_STRING (type));
+                   cp_error ("type `%T' is not an immediate or virtual basetype for `%T'",
+                             basetype, type);
                  else
-                   error ("type `%s' is not an immediate basetype for `%s'",
-                          IDENTIFIER_POINTER (name),
-                          TYPE_NAME_STRING (type));
+                   cp_error ("type `%T' is not an immediate basetype for `%T'",
+                             basetype, type);
                  return;
                }
            }
 
-         if (purpose_member (name, current_base_init_list))
+         if (purpose_member (basetype, current_base_init_list))
            {
-             error ("base class `%s' already initialized",
-                    IDENTIFIER_POINTER (name));
+             cp_error ("base class `%T' already initialized", basetype);
              return;
            }
 
          if (warn_reorder && current_member_init_list)
            {
-             warning ("base initializer for `%s'", IDENTIFIER_POINTER (name));
+             cp_warning ("base initializer for `%T'", basetype);
              warning ("   will be re-ordered to precede member initializations");
            }
 
-         base_init = build_tree_list (name, init);
-         TREE_TYPE (base_init) = basetype;
+         base_init = build_tree_list (basetype, init);
          current_base_init_list = chainon (current_base_init_list, base_init);
        }
       else
@@ -1024,12 +1024,11 @@ expand_member_init (exp, name, init)
 
          if (purpose_member (name, current_member_init_list))
            {
-             error ("field `%s' already initialized", IDENTIFIER_POINTER (name));
+             cp_error ("field `%D' already initialized", field);
              return;
            }
 
          member_init = build_tree_list (name, init);
-         TREE_TYPE (member_init) = TREE_TYPE (field);
          current_member_init_list = chainon (current_member_init_list, member_init);
        }
       return;
@@ -1741,6 +1740,26 @@ is_aggr_typedef (name, or_else)
   return 1;
 }
 
+/* Report an error if TYPE is not a user-defined, aggregate type.  If
+   OR_ELSE is nonzero, give an error message.  */
+int
+is_aggr_type (type, or_else)
+     tree type;
+     int or_else;
+{
+  if (type == error_mark_node)
+    return 0;
+
+  if (! IS_AGGR_TYPE (type)
+      && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
+    {
+      if (or_else)
+       cp_error ("`%T' is not an aggregate type", type);
+      return 0;
+    }
+  return 1;
+}
+
 /* Like is_aggr_typedef, but returns typedef if successful.  */
 tree
 get_aggr_from_typedef (name, or_else)
@@ -1788,13 +1807,13 @@ get_type_value (name)
 /* This code could just as well go in `class.c', but is placed here for
    modularity.  */
 
-/* For an expression of the form CNAME :: NAME (PARMLIST), build
+/* For an expression of the form TYPE :: NAME (PARMLIST), build
    the appropriate function call.  */
 tree
-build_member_call (cname, name, parmlist)
-     tree cname, name, parmlist;
+build_member_call (type, name, parmlist)
+     tree type, name, parmlist;
 {
-  tree type, t;
+  tree t;
   tree method_name = name;
   int dtor = 0;
   int dont_use_this = 0;
@@ -1806,22 +1825,19 @@ build_member_call (cname, name, parmlist)
       dtor = 1;
     }
 
-  if (TREE_CODE (cname) == SCOPE_REF)
-    cname = resolve_scope_to_name (NULL_TREE, cname);
-
   /* This shouldn't be here, and build_member_call shouldn't appear in
      parse.y!  (mrs)  */
-  if (cname && get_aggr_from_typedef (cname, 0) == 0
-      && TREE_CODE (cname) == IDENTIFIER_NODE)
+  if (type && TREE_CODE (type) == IDENTIFIER_NODE
+      && get_aggr_from_typedef (type, 0) == 0)
     {
-      tree ns = lookup_name (cname, 0);
+      tree ns = lookup_name (type, 0);
       if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
        {
-         return build_x_function_call (build_offset_ref (cname, name), parmlist, current_class_decl);
+         return build_x_function_call (build_offset_ref (type, name), parmlist, current_class_decl);
        }
     }
 
-  if (cname == NULL_TREE || ! (type = get_aggr_from_typedef (cname, 1)))
+  if (type == NULL_TREE || ! is_aggr_type (type, 1))
     return error_mark_node;
 
   /* An operator we did not like.  */
@@ -1914,29 +1930,26 @@ build_member_call (cname, name, parmlist)
 
 /* Build a reference to a member of an aggregate.  This is not a
    C++ `&', but really something which can have its address taken,
-   and then act as a pointer to member, for example CNAME :: FIELD
-   can have its address taken by saying & CNAME :: FIELD.
+   and then act as a pointer to member, for example TYPE :: FIELD
+   can have its address taken by saying & TYPE :: FIELD.
 
    @@ Prints out lousy diagnostics for operator <typename>
    @@ fields.
 
    @@ This function should be rewritten and placed in search.c.  */
 tree
-build_offset_ref (cname, name)
-     tree cname, name;
+build_offset_ref (type, name)
+     tree type, name;
 {
-  tree decl, type, fnfields, fields, t = error_mark_node;
+  tree decl, fnfields, fields, t = error_mark_node;
   tree basetypes = NULL_TREE;
   int dtor = 0;
 
-  if (TREE_CODE (cname) == SCOPE_REF)
-    cname = resolve_scope_to_name (NULL_TREE, cname);
-
   /* Handle namespace names fully here.  */
-  if (TREE_CODE (cname) == IDENTIFIER_NODE
-      && get_aggr_from_typedef (cname, 0) == 0)
+  if (TREE_CODE (type) == IDENTIFIER_NODE
+      && get_aggr_from_typedef (type, 0) == 0)
     {
-      tree ns = lookup_name (cname, 0);
+      tree ns = lookup_name (type, 0);
       tree val;
       if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
        {
@@ -1948,17 +1961,18 @@ build_offset_ref (cname, name)
        }
     }
 
-  if (cname == NULL_TREE || ! is_aggr_typedef (cname, 1))
+  if (type == NULL_TREE || ! is_aggr_type (type, 1))
     return error_mark_node;
 
-  type = IDENTIFIER_TYPE_VALUE (cname);
-
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
       dtor = 1;
       name = TREE_OPERAND (name, 0);
     }
 
+  if (name == constructor_name_full (type))
+    name = constructor_name (type);
+
   if (TYPE_SIZE (type) == 0)
     {
       t = IDENTIFIER_CLASS_VALUE (name);
@@ -1983,24 +1997,14 @@ build_offset_ref (cname, name)
       return error_mark_node;
     }
 
-#if 0
-  if (TREE_CODE (name) == TYPE_EXPR)
-    /* Pass a TYPE_DECL to build_component_type_expr.  */
-    return build_component_type_expr (TYPE_NAME (TREE_TYPE (cname)),
-                                     name, NULL_TREE, 1);
-#endif
-
   if (current_class_type == 0
       || get_base_distance (type, current_class_type, 0, &basetypes) == -1)
     {
       basetypes = TYPE_BINFO (type);
-      decl = build1 (NOP_EXPR,
-                    IDENTIFIER_TYPE_VALUE (cname),
-                    error_mark_node);
+      decl = build1 (NOP_EXPR, type, error_mark_node);
     }
   else if (current_class_decl == 0)
-    decl = build1 (NOP_EXPR, IDENTIFIER_TYPE_VALUE (cname),
-                  error_mark_node);
+    decl = build1 (NOP_EXPR, type, error_mark_node);
   else
     decl = C_C_D;
 
@@ -2044,18 +2048,18 @@ build_offset_ref (cname, name)
 
          if (DECL_CHAIN (t) == NULL_TREE || dtor)
            {
-             enum access_type access;
+             tree access;
 
              /* unique functions are handled easily.  */
            unique:
              access = compute_access (basetypes, t);
-             if (access == access_protected)
+             if (access == access_protected_node)
                {
                  cp_error_at ("member function `%#D' is protected", t);
                  error ("in this context");
                  return error_mark_node;
                }
-             if (access == access_private)
+             if (access == access_private_node)
                {
                  cp_error_at ("member function `%#D' is private", t);
                  error ("in this context");
@@ -2066,7 +2070,7 @@ build_offset_ref (cname, name)
            }
 
          /* overloaded functions may need more work.  */
-         if (cname == name)
+         if (name == constructor_name (type))
            {
              if (TYPE_HAS_DESTRUCTOR (type)
                  && DECL_CHAIN (DECL_CHAIN (t)) == NULL_TREE)
@@ -2134,11 +2138,13 @@ build_offset_ref (cname, name)
     }
 
   /* static class functions too.  */
-  if (TREE_CODE (t) == FUNCTION_DECL && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
+  if (TREE_CODE (t) == FUNCTION_DECL
+      && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
     my_friendly_abort (53);
 
-  /* In member functions, the form `cname::name' is no longer
-     equivalent to `this->cname::name'.  */
+  /* In member functions, the form `type::name' is no longer
+     equivalent to `this->type::name', at least not until
+     resolve_offset_ref.  */
   return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);
 }
 
@@ -2271,8 +2277,7 @@ resolve_offset_ref (exp)
          || (TREE_CODE (base) == NOP_EXPR
              && TREE_OPERAND (base, 0) == error_mark_node)))
     {
-      tree basetype_path;
-      enum access_type access;
+      tree basetype_path, access;
 
       if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
        basetype = TYPE_OFFSET_BASETYPE (type);
@@ -2288,16 +2293,16 @@ resolve_offset_ref (exp)
        }
       addr = convert_pointer_to (basetype, base);
       access = compute_access (basetype_path, member);
-      if (access == access_public)
+      if (access == access_public_node)
        return build (COMPONENT_REF, TREE_TYPE (member),
                      build_indirect_ref (addr, NULL_PTR), member);
-      if (access == access_protected)
+      if (access == access_protected_node)
        {
          cp_error_at ("member `%D' is protected", member);
          error ("in this context");
          return error_mark_node;
        }
-      if (access == access_private)
+      if (access == access_private_node)
        {
          cp_error_at ("member `%D' is private", member);
          error ("in this context");
@@ -3928,15 +3933,15 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
 
       if (flags & LOOKUP_PROTECT)
        {
-         enum access_type access = compute_access (basetypes, dtor);
+         tree access = compute_access (basetypes, dtor);
 
-         if (access == access_private)
+         if (access == access_private_node)
            {
              if (flags & LOOKUP_COMPLAIN)
                cp_error ("destructor for type `%T' is private in this scope", type);
              return error_mark_node;
            }
-         else if (access == access_protected)
+         else if (access == access_protected_node)
            {
              if (flags & LOOKUP_COMPLAIN)
                cp_error ("destructor for type `%T' is protected in this scope", type);
index 7795933..abab8fb 100644 (file)
@@ -3018,9 +3018,8 @@ do_identifier (token)
       if (IDENTIFIER_CLASS_VALUE (token) == id)
        {
          /* Check access.  */
-         enum access_type access
-           = compute_access (TYPE_BINFO (current_class_type), id);
-         if (access == access_private)
+         tree access = compute_access (TYPE_BINFO (current_class_type), id);
+         if (access == access_private_node)
            cp_error ("enum `%D' is private", id);
          /* protected is OK, since it's an enum of `this'.  */
        }
@@ -3279,13 +3278,13 @@ real_yylex ()
                      switch (ptr->rid)
                        {
                        case RID_PUBLIC:
-                         yylval.itype = access_public;
+                         yylval.ttype = access_public_node;
                          break;
                        case RID_PRIVATE:
-                         yylval.itype = access_private;
+                         yylval.ttype = access_private_node;
                          break;
                        case RID_PROTECTED:
-                         yylval.itype = access_protected;
+                         yylval.ttype = access_protected_node;
                          break;
                        default:
                          my_friendly_abort (63);
@@ -4394,6 +4393,13 @@ done:
   return value;
 }
 
+int
+is_rid (t)
+     tree t;
+{
+  return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
+}
+
 typedef enum
 {
   d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
index d50ea90..7e41536 100644 (file)
@@ -1582,8 +1582,7 @@ hack_identifier (value, name, yychar)
       if (DECL_LANG_SPECIFIC (value)
          && DECL_CLASS_CONTEXT (value) != current_class_type)
        {
-         tree path;
-         enum access_type access;
+         tree path, access;
          register tree context
            = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
              ? DECL_CLASS_CONTEXT (value)
@@ -1593,7 +1592,7 @@ hack_identifier (value, name, yychar)
          if (path)
            {
              access = compute_access (path, value);
-             if (access != access_public)
+             if (access != access_public_node)
                {
                  if (TREE_CODE (value) == VAR_DECL)
                    error ("static member `%s' is %s",
@@ -2101,7 +2100,7 @@ do_build_copy_constructor (fndecl)
            (build_reference_type (basetype), parm,
             CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
          p = convert_from_reference (p);
-         current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),
+         current_base_init_list = tree_cons (basetype,
                                              p, current_base_init_list);
        }
        
@@ -2116,7 +2115,7 @@ do_build_copy_constructor (fndecl)
            (build_reference_type (basetype), parm,
             CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
          p = convert_from_reference (p);
-         current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),
+         current_base_init_list = tree_cons (basetype,
                                              p, current_base_init_list);
        }
       for (; fields; fields = TREE_CHAIN (fields))
@@ -2192,8 +2191,7 @@ do_build_assign_ref (fndecl)
                (build_reference_type (basetype), parm,
                 CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
              p = convert_from_reference (p);
-             p = build_member_call (TYPE_NESTED_NAME (basetype),
-                                    ansi_opname [MODIFY_EXPR],
+             p = build_member_call (basetype, ansi_opname [MODIFY_EXPR],
                                     build_tree_list (NULL_TREE, p));
              expand_expr_stmt (p);
            }
index d36624a..e3c2607 100644 (file)
@@ -140,7 +140,7 @@ empty_parms ()
 
 /* the reserved words... C++ extensions */
 %token <ttype> AGGR
-%token <itype> VISSPEC
+%token <ttype> VISSPEC
 %token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE
 %token NAMESPACE TYPENAME_KEYWORD USING
 %token LEFT_RIGHT TEMPLATE
@@ -236,7 +236,7 @@ empty_parms ()
 %type <ttype> named_complex_class_head_sans_basetype
 %type <ttype> unnamed_class_head
 %type <ttype> class_head base_class_list
-%type <itype> base_class_access_list
+%type <ttype> base_class_access_list
 %type <ttype> base_class maybe_base_class_list base_class.1
 %type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers
 %type <ttype> operator_name
@@ -779,13 +779,13 @@ member_init: '(' nonnull_exprlist ')'
                  expand_member_init (C_C_D, NULL_TREE, void_type_node);
                }
        | notype_identifier '(' nonnull_exprlist ')'
-               { expand_member_init (C_C_D, $<ttype>$, $3); }
+               { expand_member_init (C_C_D, $1, $3); }
        | notype_identifier LEFT_RIGHT
-               { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
+               { expand_member_init (C_C_D, $1, void_type_node); }
        | complete_type_name '(' nonnull_exprlist ')'
-               { expand_member_init (C_C_D, $<ttype>$, $3); }
+               { expand_member_init (C_C_D, $1, $3); }
        | complete_type_name LEFT_RIGHT
-               { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
+               { expand_member_init (C_C_D, $1, void_type_node); }
        /* GNU extension */
        | notype_qualified_id '(' nonnull_exprlist ')'
                {
@@ -1589,7 +1589,7 @@ primary:
        | object overqualified_id '(' nonnull_exprlist ')'
                {
                  got_object = NULL_TREE;
-                 if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
+                 if (IS_SIGNATURE (OP0 ($2)))
                    {
                      warning ("signature name in scope resolution ignored");
                      $$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE,
@@ -1601,7 +1601,7 @@ primary:
        | object overqualified_id LEFT_RIGHT
                {
                  got_object = NULL_TREE;
-                 if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
+                 if (IS_SIGNATURE (OP0 ($2)))
                    {
                      warning ("signature name in scope resolution ignored");
                      $$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE,
@@ -2349,9 +2349,8 @@ base_class_list:
 base_class:
          base_class.1
                {
-                 tree type;
-                 type = IDENTIFIER_TYPE_VALUE ($$);
-                 if (! is_aggr_typedef ($$, 1))
+                 tree type = $1;
+                 if (! is_aggr_type (type, 1))
                    $$ = NULL_TREE;
                  else if (current_aggr == signature_type_node
                           && (! type) && (! IS_SIGNATURE (type)))
@@ -2363,7 +2362,7 @@ base_class:
                    {
                      sorry ("signature inheritance, base type `%s' ignored",
                             IDENTIFIER_POINTER ($$));
-                     $$ = build_tree_list ((tree)access_public, $$);
+                     $$ = build_tree_list (access_public_node, $$);
                    }
                  else if (type && IS_SIGNATURE (type))
                    {
@@ -2371,15 +2370,14 @@ base_class:
                      $$ = NULL_TREE;
                    }
                  else
-                   $$ = build_tree_list ((tree)access_default, $$);
+                   $$ = build_tree_list (access_default_node, $$);
                }
        | base_class_access_list see_typename base_class.1
                {
-                 tree type;
-                 type = IDENTIFIER_TYPE_VALUE ($3);
+                 tree type = $3;
                  if (current_aggr == signature_type_node)
                    error ("access and source specifiers not allowed in signature");
-                 if (! is_aggr_typedef ($3, 1))
+                 if (! IS_AGGR_TYPE (type))
                    $$ = NULL_TREE;
                  else if (current_aggr == signature_type_node
                           && (! type) && (! IS_SIGNATURE (type)))
@@ -2391,7 +2389,7 @@ base_class:
                    {
                      sorry ("signature inheritance, base type `%s' ignored",
                             IDENTIFIER_POINTER ($$));
-                     $$ = build_tree_list ((tree)access_public, $3);
+                     $$ = build_tree_list (access_public_node, $3);
                    }
                  else if (type && IS_SIGNATURE (type))
                    {
@@ -2399,7 +2397,7 @@ base_class:
                      $$ = NULL_TREE;
                    }
                  else
-                   $$ = build_tree_list ((tree) $$, $3);
+                   $$ = build_tree_list ($$, $3);
                }
        ;
 
@@ -2412,8 +2410,7 @@ base_class.1:
                      if (IS_AGGR_TYPE (TREE_TYPE ($3)))
                        {
                          sorry ("`sigof' as base signature specifier");
-                         /* need to return some dummy signature identifier */
-                         $$ = $3;
+                         $$ = TREE_TYPE ($3);
                        }
                      else
                        {
@@ -2434,8 +2431,7 @@ base_class.1:
                      if (IS_AGGR_TYPE (groktypename ($3)))
                        {
                          sorry ("`sigof' as base signature specifier");
-                         /* need to return some dummy signature identifier */
-                         $$ = $3;
+                         $$ = groktypename ($3);
                        }
                      else
                        {
@@ -2456,40 +2452,40 @@ base_class_access_list:
        | SCSPEC see_typename
                { if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL])
                    sorry ("non-virtual access");
-                 $$ = access_default_virtual; }
+                 $$ = access_default_virtual_node; }
        | base_class_access_list VISSPEC see_typename
                { int err = 0;
-                 if ($2 == access_protected)
+                 if ($2 == access_protected_node)
                    {
                      warning ("`protected' access not implemented");
-                     $2 = access_public;
+                     $2 = access_public_node;
                      err++;
                    }
-                 else if ($2 == access_public)
+                 else if ($2 == access_public_node)
                    {
-                     if ($1 == access_private)
+                     if ($1 == access_private_node)
                        {
                        mixed:
                          error ("base class cannot be public and private");
                        }
-                     else if ($1 == access_default_virtual)
-                       $$ = access_public_virtual;
+                     else if ($1 == access_default_virtual_node)
+                       $$ = access_public_virtual_node;
                    }
-                 else /* $2 == access_private */
+                 else /* $2 == access_private_node */
                    {
-                     if ($1 == access_public)
+                     if ($1 == access_public_node)
                        goto mixed;
-                     else if ($1 == access_default_virtual)
-                       $$ = access_private_virtual;
+                     else if ($1 == access_default_virtual_node)
+                       $$ = access_private_virtual_node;
                    }
                }
        | base_class_access_list SCSPEC see_typename
                { if ($2 != ridpointers[(int)RID_VIRTUAL])
                    sorry ("non-virtual access");
-                 if ($$ == access_public)
-                   $$ = access_public_virtual;
-                 else if ($$ == access_private)
-                   $$ = access_private_virtual; }
+                 if ($$ == access_public_node)
+                   $$ = access_public_virtual_node;
+                 else if ($$ == access_private_node)
+                   $$ = access_private_virtual_node; }
        ;
 
 left_curly: '{'
@@ -2564,18 +2560,18 @@ opt.component_decl_list:
        | component_decl_list
                {
                  if (current_aggr == signature_type_node)
-                   $$ = build_tree_list ((tree) access_public, $$);
+                   $$ = build_tree_list (access_public_node, $$);
                  else
-                   $$ = build_tree_list ((tree) access_default, $$);
+                   $$ = build_tree_list (access_default_node, $$);
                }
        | opt.component_decl_list VISSPEC ':' component_decl_list
                {
-                 tree visspec = (tree) $2;
+                 tree visspec = $2;
 
                  if (current_aggr == signature_type_node)
                    {
                      error ("access specifier not allowed in signature");
-                     visspec = (tree) access_public;
+                     visspec = access_public_node;
                    }
                  $$ = chainon ($$, build_tree_list (visspec, $4));
                }
@@ -2861,23 +2857,20 @@ after_type_declarator:
 qualified_type_name:
          type_name %prec EMPTY
                {
+                 $$ = TREE_TYPE ($1);
                  /* Remember that this name has been used in the class
                     definition, as per [class.scope0] */
                  if (current_class_type
                      && TYPE_BEING_DEFINED (current_class_type)
-                     && ! IDENTIFIER_CLASS_VALUE ($$))
-                   {
-                     tree t = lookup_name ($$, -2);
-                     if (t)
-                       pushdecl_class_level (t);
-                   }
+                     && ! IDENTIFIER_CLASS_VALUE ($1))
+                   pushdecl_class_level (lookup_name ($1, -2));
                }
        | nested_type
        ;
 
 nested_type:
        nested_name_specifier type_name %prec EMPTY
-               { $$ = $2; }
+               { $$ = TREE_TYPE ($2); }
        ;
 
 direct_after_type_declarator:
@@ -2941,9 +2934,9 @@ complex_direct_notype_declarator:
        | direct_notype_declarator '[' ']'
                { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
        | notype_qualified_id
-               { if (TREE_TYPE (OP0 ($$)) != current_class_type)
+               { if (OP0 ($$) != current_class_type)
                    {
-                     push_nested_class (TREE_TYPE (OP0 ($$)), 3);
+                     push_nested_class (OP0 ($$), 3);
                      TREE_COMPLEXITY ($$) = current_class_depth;
                    }
                }
@@ -2991,11 +2984,11 @@ nested_name_specifier:
    inline here?!?  (jason) */
 nested_name_specifier_1:
          TYPENAME SCOPE
-               { got_scope = TREE_TYPE ($$); }
+               { got_scope = $$ = TREE_TYPE ($1); }
        | NSNAME SCOPE
-               { got_scope = $$; }
+               { got_scope = $$ = $1; }
        | template_type SCOPE
-               { got_scope = TREE_TYPE ($$); }
+               { got_scope = $$ = TREE_TYPE ($1); }
 /*     These break 'const i;'
        | IDENTIFIER SCOPE
                {
index b80bff0..ffc7f33 100644 (file)
@@ -127,13 +127,6 @@ process_template_parm (list, next)
       decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
       TYPE_MAIN_DECL (t) = decl;
       parm = decl;
-      if (defval)
-       {
-         if (IDENTIFIER_HAS_TYPE_VALUE (defval))
-           defval = IDENTIFIER_TYPE_VALUE (defval);
-         else
-           defval = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (defval));
-       }
     }
   SET_DECL_ARTIFICIAL (decl);
   pushdecl (decl);
index 14b8d01..110eaed 100644 (file)
@@ -794,23 +794,23 @@ current_scope ()
 
    This will be static when lookup_fnfield comes into this file.
 
-   access_public means that the field can be accessed by the current lexical
+   access_public_node means that the field can be accessed by the current lexical
    scope.
 
-   access_protected means that the field cannot be accessed by the current
+   access_protected_node means that the field cannot be accessed by the current
    lexical scope because it is protected.
 
-   access_private means that the field cannot be accessed by the current
+   access_private_node means that the field cannot be accessed by the current
    lexical scope because it is private. */
 
 #if 0
-#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public
-#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected
-#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private
+#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public_node
+#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected_node
+#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private_node
 #else
-#define PUBLIC_RETURN return access_public
-#define PROTECTED_RETURN return access_protected
-#define PRIVATE_RETURN return access_private
+#define PUBLIC_RETURN return access_public_node
+#define PROTECTED_RETURN return access_protected_node
+#define PRIVATE_RETURN return access_private_node
 #endif
 
 #if 0
@@ -818,11 +818,11 @@ current_scope ()
 static tree previous_scope = NULL_TREE;
 #endif
 
-enum access_type
+tree
 compute_access (basetype_path, field)
      tree basetype_path, field;
 {
-  enum access_type access;
+  tree access;
   tree types;
   tree context;
   int protected_ok, via_protected;
@@ -836,11 +836,11 @@ compute_access (basetype_path, field)
      || (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field)));
 
   if (! flag_access_control)
-    return access_public;
+    return access_public_node;
 
   /* The field lives in the current class.  */
   if (BINFO_TYPE (basetype_path) == current_class_type)
-    return access_public;
+    return access_public_node;
 
 #if 0
   /* Disabled until pushing function scope clears these out.  If ever.  */
@@ -848,17 +848,17 @@ compute_access (basetype_path, field)
   if (current_scope () == previous_scope)
     {
       if (DECL_PUBLIC (field))
-       return access_public;
+       return access_public_node;
       if (DECL_PROTECTED (field))
-       return access_protected;
+       return access_protected_node;
       if (DECL_PRIVATE (field))
-       return access_private;
+       return access_private_node;
     }
 #endif
 
   /* We don't currently support access control on nested types.  */
   if (TREE_CODE (field) == TYPE_DECL)
-    return access_public;
+    return access_public_node;
 
   previous_scope = current_scope ();
   
@@ -912,7 +912,7 @@ compute_access (basetype_path, field)
   basetype_path = reverse_path (basetype_path);
   types = basetype_path;
   via_protected = 0;
-  access = access_default;
+  access = access_default_node;
   protected_ok = static_mem && current_class_type
     && ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type);
 
@@ -934,7 +934,7 @@ compute_access (basetype_path, field)
       member = purpose_member (type, DECL_ACCESS (field));
       if (member)
        {
-         access = (enum access_type) TREE_VALUE (member);
+         access = TREE_VALUE (member);
          break;
        }
 
@@ -948,7 +948,7 @@ compute_access (basetype_path, field)
            via_protected = 1;
          else if (! TREE_VIA_PUBLIC (types) && ! private_ok)
            {
-             access = access_private;
+             access = access_private_node;
              break;
            }
        }
@@ -959,30 +959,30 @@ compute_access (basetype_path, field)
 
   /* No special visibilities apply.  Use normal rules.  */
 
-  if (access == access_default)
+  if (access == access_default_node)
     {
       if (is_friend (context, previous_scope))
-       access = access_public;
+       access = access_public_node;
       else if (TREE_PRIVATE (field))
-       access = access_private;
+       access = access_private_node;
       else if (TREE_PROTECTED (field))
-       access = access_protected;
+       access = access_protected_node;
       else
-       access = access_public;
+       access = access_public_node;
     }
 
-  if (access == access_public && via_protected)
-    access = access_protected;
+  if (access == access_public_node && via_protected)
+    access = access_protected_node;
 
-  if (access == access_protected && protected_ok)
-    access = access_public;
+  if (access == access_protected_node && protected_ok)
+    access = access_public_node;
 
 #if 0
-  if (access == access_public)
+  if (access == access_public_node)
     DECL_PUBLIC (field) = 1;
-  else if (access == access_protected)
+  else if (access == access_protected_node)
     DECL_PROTECTED (field) = 1;
-  else if (access == access_private)
+  else if (access == access_private_node)
     DECL_PRIVATE (field) = 1;
   else my_friendly_abort (96);
 #endif
@@ -1072,9 +1072,9 @@ lookup_field (xbasetype, name, protect, want_type)
   int head = 0, tail = 0;
   tree rval, rval_binfo = NULL_TREE, rval_binfo_h;
   tree type, basetype_chain, basetype_path;
-  enum access_type this_v = access_default;
+  tree this_v = access_default_node;
   tree entry, binfo, binfo_h;
-  enum access_type own_access = access_default;
+  tree own_access = access_default_node;
   int vbase_name_p = VBASE_NAME_P (name);
 
   /* rval_binfo is the binfo associated with the found member, note,
@@ -1179,16 +1179,16 @@ lookup_field (xbasetype, name, protect, want_type)
            this_v = compute_access (basetype_path, rval);
          if (TREE_CODE (rval) == CONST_DECL)
            {
-             if (this_v == access_private)
+             if (this_v == access_private_node)
                errstr = "enum `%D' is a private value of class `%T'";
-             else if (this_v == access_protected)
+             else if (this_v == access_protected_node)
                errstr = "enum `%D' is a protected value of class `%T'";
            }
          else
            {
-             if (this_v == access_private)
+             if (this_v == access_private_node)
                errstr = "member `%D' is a private member of class `%T'";
-             else if (this_v == access_protected)
+             else if (this_v == access_protected_node)
                errstr = "member `%D' is a protected member of class `%T'";
            }
        }
@@ -1370,14 +1370,14 @@ lookup_field (xbasetype, name, protect, want_type)
            /* If is possible for one of the derived types on the path to
               have defined special access for this field.  Look for such
               declarations and report an error if a conflict is found.  */
-           enum access_type new_v;
+           tree new_v;
 
-           if (this_v != access_default)
+           if (this_v != access_default_node)
              new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval);
-           if (this_v != access_default && new_v != this_v)
+           if (this_v != access_default_node && new_v != this_v)
              {
                errstr = "conflicting access to member `%D'";
-               this_v = access_default;
+               this_v = access_default_node;
              }
            own_access = new_v;
            CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
@@ -1397,15 +1397,15 @@ lookup_field (xbasetype, name, protect, want_type)
 
   if (errstr == 0)
     {
-      if (own_access == access_private)
+      if (own_access == access_private_node)
        errstr = "member `%D' declared private";
-      else if (own_access == access_protected)
+      else if (own_access == access_protected_node)
        errstr = "member `%D' declared protected";
-      else if (this_v == access_private)
+      else if (this_v == access_private_node)
        errstr = TREE_PRIVATE (rval)
          ? "member `%D' is private"
            : "member `%D' is from private base class";
-      else if (this_v == access_protected)
+      else if (this_v == access_protected_node)
        errstr = TREE_PROTECTED (rval)
          ? "member `%D' is protected"
            : "member `%D' is from protected base class";
@@ -3334,10 +3334,14 @@ dfs_compress_decls (binfo)
    lattice.  Where ambiguities result, we mark them
    with `error_mark_node' so that if they are encountered
    without explicit qualification, we can emit an error
-   message.  */
+   message.
+
+   ONLY_TYPES is set when defining TYPE so that inherited types are visible
+   in the derived class.  */
 void
-push_class_decls (type)
+push_class_decls (type, only_types)
      tree type;
+     int only_types;
 {
   tree id;
   struct obstack *ambient_obstack = current_obstack;
@@ -3392,7 +3396,12 @@ push_class_decls (type)
       /* Install the original class value in order to make
         pushdecl_class_level work correctly.  */
       IDENTIFIER_CLASS_VALUE (id) = TREE_VALUE (closed_envelopes);
-      if (TREE_CODE (new) == TREE_LIST)
+      if (only_types)
+       {
+         if (TREE_CODE (new) == TYPE_DECL)
+           set_identifier_type_value (id, TREE_TYPE (new));
+       } 
+      else if (TREE_CODE (new) == TREE_LIST)
        push_class_level_binding (id, new);
       else
        pushdecl_class_level (new);
index 0337ce3..27d4e2e 100644 (file)
@@ -530,7 +530,7 @@ build_signature_table_constructor (sig_ty, rhs)
 
          if (rhs_method == NULL_TREE
              || (compute_access (basetypes, rhs_method)
-                 != access_public))
+                 != access_public_node))
            {
              error ("class `%s' does not contain a method conforming to `%s'",
                     TYPE_NAME_STRING (rhstype),
index 7fb688e..be0fc99 100644 (file)
@@ -820,8 +820,8 @@ layout_basetypes (rec, binfos)
                goto got_it;
            }
          sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype));
-         decl = build_lang_decl (FIELD_DECL, get_identifier (name),
-                                 build_pointer_type (basetype));
+         decl = build_lang_field_decl (FIELD_DECL, get_identifier (name),
+                                       build_pointer_type (basetype));
          /* If you change any of the below, take a look at all the
             other VFIELD_BASEs and VTABLE_BASEs in the code, and change
             them too. */
@@ -1137,7 +1137,8 @@ get_decl_list (value)
   if (TREE_CODE (value) == IDENTIFIER_NODE)
     list = get_identifier_list (value);
   else if (TREE_CODE (value) == RECORD_TYPE
-          && TYPE_LANG_SPECIFIC (value))
+          && TYPE_LANG_SPECIFIC (value)
+          && value == TYPE_MAIN_VARIANT (value))
     list = CLASSTYPE_AS_LIST (value);
 
   if (list != NULL_TREE)
index 3cb6d79..9901080 100644 (file)
@@ -1532,15 +1532,14 @@ build_object_ref (datum, basetype, field)
                basetype, field, dtype);
       return error_mark_node;
     }
-  else if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (basetype)))
+  else if (IS_SIGNATURE (basetype))
     {
       warning ("signature name in scope resolution ignored");
       return build_component_ref (datum, field, NULL_TREE, 1);
     }
-  else if (is_aggr_typedef (basetype, 1))
+  else if (is_aggr_type (basetype, 1))
     {
-      tree real_basetype = IDENTIFIER_TYPE_VALUE (basetype);
-      tree binfo = binfo_or_else (real_basetype, TREE_TYPE (datum));
+      tree binfo = binfo_or_else (basetype, TREE_TYPE (datum));
       if (binfo)
        return build_component_ref (build_scoped_ref (datum, basetype),
                                    field, binfo, 1);
@@ -1590,15 +1589,14 @@ build_component_ref_1 (datum, field, protect)
 
   if (datum == C_C_D)
     {
-      enum access_type access
-       = compute_access (TYPE_BINFO (current_class_type), field);
+      tree access = compute_access (TYPE_BINFO (current_class_type), field);
 
-      if (access == access_private)
+      if (access == access_private_node)
        {
          cp_error ("field `%D' is private", field);
          return error_mark_node;
        }
-      else if (access == access_protected)
+      else if (access == access_protected_node)
        {
          cp_error ("field `%D' is protected", field);
          return error_mark_node;
@@ -1748,14 +1746,13 @@ build_component_ref (datum, component, basetype_path, protect)
              if (TREE_CHAIN (fndecls) == NULL_TREE
                  && DECL_CHAIN (TREE_VALUE (fndecls)) == NULL_TREE)
                {
-                 enum access_type access;
-                 tree fndecl;
+                 tree access, fndecl;
 
                  /* Unique, so use this one now.  */
                  basetype = TREE_PURPOSE (fndecls);
                  fndecl = TREE_VALUE (fndecls);
                  access = compute_access (TREE_PURPOSE (fndecls), fndecl);
-                 if (access == access_public)
+                 if (access == access_public_node)
                    {
                      if (DECL_VINDEX (fndecl)
                          && ! resolves_to_fixed_type_p (datum, 0))
@@ -1769,7 +1766,7 @@ build_component_ref (datum, component, basetype_path, protect)
                      mark_used (fndecl);
                      return fndecl;
                    }
-                 if (access == access_protected)
+                 if (access == access_protected_node)
                    cp_error ("member function `%D' is protected", fndecl);
                  else
                    cp_error ("member function `%D' is private", fndecl);
@@ -3727,7 +3724,7 @@ pointer_int_sum (resultcode, ptrop, intop)
     }
   else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE)
     {
-      if (pedantic)
+      if (pedantic || warn_pointer_arith)
        pedwarn ("ANSI C++ forbids using pointer to a member in arithmetic");
       size_exp = integer_one_node;
     }
@@ -3793,7 +3790,7 @@ pointer_diff (op0, op1)
   tree restype = ptrdiff_type_node;
   tree target_type = TREE_TYPE (TREE_TYPE (op0));
 
-  if (pedantic)
+  if (pedantic || warn_pointer_arith)
     {
       if (TREE_CODE (target_type) == VOID_TYPE)
        pedwarn ("ANSI C++ forbids using pointer of type `void *' in subtraction");
@@ -6169,9 +6166,10 @@ build_modify_expr (lhs, modifycode, rhs)
       /* Can't initialize directly from a TARGET_EXPR, since that would
         cause the lhs to be constructed twice, and possibly result in
         accidental self-initialization.  So we force the TARGET_EXPR to be
-        expanded.  expand_expr should really do this by itself.  */
+        expanded without a target.  */
       if (TREE_CODE (newrhs) == TARGET_EXPR)
-       newrhs = expand_target_expr (newrhs);
+       newrhs = build (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
+                       TREE_VALUE (newrhs));
     }
 
   if (TREE_CODE (newrhs) == ERROR_MARK)
index 02ac42d..a2f8172 100644 (file)
@@ -1199,7 +1199,7 @@ process_init_constructor (type, init, elts)
 \f
 /* Given a structure or union value DATUM, construct and return
    the structure or union component which results from narrowing
-   that value by the types specified in TYPES.  For example, given the
+   that value by the type specified in BASETYPE.  For example, given the
    hierarchy
 
    class L { int ii; };
@@ -1213,23 +1213,16 @@ process_init_constructor (type, init, elts)
 
    then the expression
 
-   x::C::A::L::ii refers to the ii member of the L part of
+   x.A::ii refers to the ii member of the L part of
    of A part of the C object named by X.  In this case,
-   DATUM would be x, and TYPES would be a SCOPE_REF consisting of
-
-       SCOPE_REF
-               SCOPE_REF
-                       C       A
-               L
-
-   The last entry in the SCOPE_REF is always an IDENTIFIER_NODE.
+   DATUM would be x, and BASETYPE would be A.
 
 */
 
 tree
-build_scoped_ref (datum, types)
+build_scoped_ref (datum, basetype)
      tree datum;
-     tree types;
+     tree basetype;
 {
   tree ref;
   tree type = TREE_TYPE (datum);
@@ -1242,62 +1235,17 @@ build_scoped_ref (datum, types)
 
   type = TYPE_MAIN_VARIANT (type);
 
-  if (TREE_CODE (types) == SCOPE_REF)
-    {
-      /* We have some work to do.  */
-      struct type_chain
-       { tree type; struct type_chain *next; }
-      *chain = NULL, *head = NULL, scratch;
-      ref = build_unary_op (ADDR_EXPR, datum, 0);
-      while (TREE_CODE (types) == SCOPE_REF)
-       {
-         tree t = TREE_OPERAND (types, 1);
-         if (is_aggr_typedef (t, 1))
-           {
-             head = (struct type_chain *)alloca (sizeof (struct type_chain));
-             head->type = IDENTIFIER_TYPE_VALUE (t);
-             head->next = chain;
-             chain = head;
-             types = TREE_OPERAND (types, 0);
-           }
-         else return error_mark_node;
-       }
-      if (! is_aggr_typedef (types, 1))
-       return error_mark_node;
-
-      head = &scratch;
-      head->type = IDENTIFIER_TYPE_VALUE (types);
-      head->next = chain;
-      chain = head;
-      while (chain)
-       {
-         tree binfo = chain->type;
-         type = TREE_TYPE (TREE_TYPE (ref));
-         if (binfo != TYPE_BINFO (type))
-           {
-             binfo = get_binfo (binfo, type, 1);
-             if (binfo == error_mark_node)
-               return error_mark_node;
-             if (binfo == 0)
-               return error_not_base_type (chain->type, type);
-             ref = convert_pointer_to (binfo, ref);
-           }
-         chain = chain->next;
-       }
-      return build_indirect_ref (ref, "(compiler error in build_scoped_ref)");
-    }
-
   /* This is an easy conversion.  */
-  if (is_aggr_typedef (types, 1))
+  if (is_aggr_type (basetype, 1))
     {
-      tree binfo = TYPE_BINFO (IDENTIFIER_TYPE_VALUE (types));
+      tree binfo = TYPE_BINFO (basetype);
       if (binfo != TYPE_BINFO (type))
        {
          binfo = get_binfo (binfo, type, 1);
          if (binfo == error_mark_node)
            return error_mark_node;
          if (binfo == 0)
-           return error_not_base_type (IDENTIFIER_TYPE_VALUE (types), type);
+           return error_not_base_type (basetype, type);
        }
 
       switch (TREE_CODE (datum))