OSDN Git Service

37th Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 May 1994 02:46:07 +0000 (02:46 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 May 1994 02:46:07 +0000 (02:46 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@7290 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/gxx.gperf
gcc/cp/hash.h
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/lex.h
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 4b3b09d..bd2be26 100644 (file)
@@ -2,6 +2,186 @@ Thu May 12 19:13:54 1994  Richard Earnshaw  (rwe11@cl.cam.ac.uk)
 
        * g++.c: Use #ifdef for __MSDOS__, not #if.
 
+Thu May 12 18:05:18 1994  Mike Stump  (mrs@cygnus.com)
+
+       * decl2.c (lang_f_options): Handle -fshort-temps.  -fshort-temps
+       gives old behavior , and destroys temporaries earlier.  Default
+       behavior now conforms to the ANSI working paper.
+
+Thu May 12 14:45:35 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * typeck.c (build_modify_expr): Understand MODIFY_EXPR as an lvalue.
+       Use convert_force to convert the result of a recursive call when we
+       are dealing with a NOP_EXPR.  Don't automatically wrap MODIFY_EXPRs
+       in COMPOUND_EXPRs any more.
+       (various): Lose pedantic_lvalue_warning.
+       (unary_complex_lvalue): Understand MODIFY_EXPR.
+
+       * cvt.c (convert_to_reference): Allow DECL to be error_mark_node if
+       we don't know what we're initializing.
+
+Wed May 11 01:59:36 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * cvt.c (convert_to_reference): Modify to use convtype parameter.
+       Only create temporaries when initializing a reference, not when
+       casting.
+       (cp_convert): New main function.
+       (convert): Call cp_convert.
+       * cvt.c, decl.c, typeck.c: Fix calls to convert_to_reference.
+       * cp-tree.h (CONV_*): New constants used by conversion code for
+       selecting conversions to perform.
+
+       * tree.c (lvalue_p): MODIFY_EXPRs are no longer lvalues.
+
+       * typeck.c (build_{static,reinterpret,const_cast): Stubs that just
+       call build_c_cast.
+       * parse.y: Add {static,reinterpret,const}_cast.
+       * gxx.gperf: Ditto.
+
+       * typeck.c (common_type): Allow methods with basetypes of different
+       UPTs.
+       (comptypes): Deal with UPTs.
+       (build_modify_expr): Wrap all MODIFY_EXPRs in a COMPOUND_EXPR.
+
+       * pt.c (end_template_decl): Check for multiple definitions of member
+       templates.
+
+       * call.c (build_method_call): Complain about calling an abstract
+       virtual from a constructor.
+
+       * typeck.c (pointer_int_sum): Check for the integer operand being 0
+       after checking the validity of the pointer operand.
+
+       * typeck2.c (digest_init): Pedwarn about string initializer being
+       too long.
+
+Tue May 10 12:10:28 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (push_overloaded_decl): Only throw away a builtin if the
+       decl in question is the artificial one.
+
+       * parse.y (simple_stmt, switch): Use implicitly_scoped_stmt because
+       expand_{start,end}_case cannot happen in the middle of a block.
+
+       * cvt.c (build_type_conversion_1): Use convert again.
+
+Tue May 10 11:52:04 1994  Brendan Kehoe  (brendan@lisa.cygnus.com)
+
+       * typeck2.c (digest_init): Make sure we check for signed and
+       unsigned chars as well when warning about string initializers.
+
+       * init.c (emit_base_init): Check if there's a DECL_NAME on the
+       member before trying to do an initialization for it.
+
+Tue May 10 11:34:37 1994  Mike Stump  (mrs@cygnus.com)
+
+       * except.c: Don't do anything useful when cross compiling.
+
+Tue May 10 03:04:13 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (duplicate_decls): Fix up handling of builtins yet again.
+       (push_overloaded_decl): Ditto.
+
+       * cvt.c (convert): Don't look for void type conversion.
+
+Mon May  9 18:05:41 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * init.c (do_friend): Only do a pushdecl for friends, not
+       pushdecl_top_level.
+
+Mon May  9 13:36:34 1994  Jim Wilson  (wilson@sphagnum.cygnus.com)
+
+       * decl.c (lookup_name_current_level): Put empty statement after
+       the label OUT to make the code valid C.
+
+Mon May  9 12:20:57 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * typeck.c (build_binary_op_nodefault): Only complain about
+       comparing void * and a function pointer if void * is smaller.
+
+Sun May  8 01:29:13 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (lookup_name_current_level): Move through temporary binding
+       levels.
+
+       * parse.y (already_scoped_stmt): Revive.
+       (simple_stmt): Use it again.
+
+       * decl.c (poplevel): Always call poplevel recursively if we're
+       dealing with a temporary binding level.
+
+Sat May  7 10:52:28 1994  Mike Stump  (mrs@cygnus.com)
+
+       * decl.c (finish_decl): Make sure we run cleanups for initial values
+       of decls.  Cures memory leak.
+       * decl.c (expand_static_init): Ditto for static variables.
+       * decl2.c (finish_file): Ditto for globals.
+
+Sat May  7 03:57:44 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * typeck.c (commonparms): Don't complain about redefining default
+       args.
+
+       * decl.c (duplicate_decls): Don't complain twice about conflicting
+       function decls.
+       (decls_match): Don't look at default args.
+       (redeclaration_error_message): Complain about redefining default
+       args.
+
+       * call.c (build_overload_call_real): Also deal with guiding
+       declarations coming BEFORE the template decl.
+
+       * pt.c (unify): Allow different parms to have different
+       cv-qualifiers.
+       (unify): Allow trivial conversions on non-template parms.
+
+Fri May  6 03:53:23 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * pt.c (tsubst): Support OFFSET_TYPEs.
+       (unify): Ditto.
+
+       * decl2.c (finish_decl_parsing): Call push_nested_class with a type.
+
+       * init.c (build_offset_ref): Fix error message.
+       * search.c (lookup_field): Ditto.
+
+       * call.c (build_scoped_method_call): Pass binfo to
+       build_method_call.
+       * typeck.c (build_object_ref): Ditto.
+
+       * typeck2.c (binfo_or_else): Don't return a _TYPE.
+
+       * class.c (finish_struct): Don't complain about re-use of inherited
+       names or shadowing of type decls.
+       * decl.c (pushdecl_class_level): Ditto.
+
+       * decl.c (finish_enum): Set the type of all the enums.
+
+       * class.c (finish_struct): Don't get confused by access decls.
+
+       * cp-tree.h (TYPE_MAIN_DECL): New macro to get the _DECL for a
+       _TYPE.  You can stop using TYPE_NAME for that now.
+
+       * parse.y: Lose doing_explicit (check $0 instead).
+       * gxx.gperf: 'template' now has a RID.
+       * lex.h (rid): Ditto.
+       * lex.c (init_lex): Set up the RID for 'template'.
+
+       * parse.y (type_specifier_seq): typed_typespecs or
+       nonempty_type_quals.  Use it.
+       (handler_args): Fix bogus syntax.
+       (raise_identifier{,s}, optional_identifier): Lose.
+       * except.c (expand_start_catch_block): Use grokdeclarator to parse
+       the catch variable.
+       (init_exception_processing): The second argument to
+       __throw_type_match is ptr_type_node.
+
+       Fri May  6 07:18:54 1994  Chip Salzenberg  (chip@fin)
+
+       [ change propagated from c-decl.c of snapshot 940429 ]
+       * cp/decl.c (finish_decl): Setting asmspec_tree should not
+       zero out the old RTL.
+
 Fri May  6 01:25:38 1994  Mike Stump  (mrs@cygnus.com)
 
        Add alpha exception handling support to the compiler.
index 8f8bac2..6700f87 100644 (file)
@@ -2672,7 +2672,7 @@ build_scoped_method_call (exp, scopes, name, parms)
        }
 
       /* Call to a method.  */
-      return build_method_call (decl, name, parms, NULL_TREE,
+      return build_method_call (decl, name, parms, binfo,
                                LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
     }
   return error_mark_node;
@@ -3597,6 +3597,13 @@ build_method_call (instance, name, parms, basetype_path, flags)
   /* From here on down, BASETYPE is the type that INSTANCE_PTR's
      type (if it exists) is a pointer to.  */
 
+  if (DECL_ABSTRACT_VIRTUAL_P (function)
+      && instance == C_C_D
+      && DECL_CONSTRUCTOR_P (current_function_decl)
+      && ! (flags & LOOKUP_NONVIRTUAL)
+      && value_member (function, get_abstract_virtuals (basetype)))
+    cp_error ("abstract virtual `%#D' called from constructor", function);
+
   if (IS_SIGNATURE (basetype) && static_call_context)
     {
       cp_error ("cannot call signature member function `%T::%D' without signature pointer/reference",
@@ -4046,22 +4053,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
                                TYPE_ARG_TYPES (TREE_TYPE (function)),
                                parms, &template_cost, 0);
          if (i == 0)
-           {
-             struct candidate *cp2;
-
-             function = instantiate_template (function, targs);
-             /* Now check that the template instantiated for this is not
-                the same as a function that's in the list due to some
-                previous instantiation.  */
-             cp2 = candidates;
-             while (cp2 != cp)
-               if (cp2->function == function)
-                 break;
-               else
-                 cp2 += 1;
-             if (cp2->function == function)
-               continue;
-           }
+           function = instantiate_template (function, targs);
        }
 
       if (TREE_CODE (function) == TEMPLATE_DECL)
@@ -4076,6 +4068,19 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
        }
       else
        {
+         struct candidate *cp2;
+
+         /* Check that this decl is not the same as a function that's in
+            the list due to some template instantiation.  */
+         cp2 = candidates;
+         while (cp2 != cp)
+           if (cp2->function == function)
+             break;
+           else
+             cp2 += 1;
+         if (cp2->function == function)
+           continue;
+
          function = DECL_MAIN_VARIANT (function);
 
          /* Can't use alloca here, since result might be
index 730d0ca..27e9a4b 100644 (file)
@@ -2734,10 +2734,22 @@ finish_struct (t, list_of_fieldlists, warn_anon)
          if (TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL)
            {
              tree name = DECL_NAME (x);
-             tree icv = name ? IDENTIFIER_CLASS_VALUE (name) : NULL_TREE;
+             tree icv;
 
-             /* Don't complain about constructors.  */
-             if (icv && name != constructor_name (current_class_type))
+             /* Don't get confused by access decls.  */
+             if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+               icv = IDENTIFIER_CLASS_VALUE (name);
+             else
+               icv = NULL_TREE;
+
+             if (icv
+                 /* Don't complain about constructors.  */
+                 && name != constructor_name (current_class_type)
+                 /* Or inherited names.  */
+                 && id_in_current_class (name)
+                 /* Or shadowed tags.  */
+                 && !(TREE_CODE (icv) == TYPE_DECL
+                      && DECL_CONTEXT (icv) == t))
                {
                  cp_error_at ("declaration of identifier `%D' as `%+#D'",
                               name, x);
index 54dc2b2..5d7cfa7 100644 (file)
@@ -321,6 +321,9 @@ enum languages { lang_c, lang_cplusplus };
 #define TYPE_ASSEMBLER_NAME_STRING(NODE) (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME  (NODE))))
 #define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
 
+/* The _DECL for this _TYPE.  */
+#define TYPE_MAIN_DECL(NODE) (TYPE_NAME (NODE))
+
 #define IS_AGGR_TYPE(t)                (TYPE_LANG_FLAG_5 (t))
 #define IS_AGGR_TYPE_CODE(t)   (t == RECORD_TYPE || t == UNION_TYPE || t == UNINSTANTIATED_P_TYPE)
 #define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
@@ -1723,6 +1726,24 @@ extern tree current_class_type;  /* _TYPE: the type of the current class */
 #define LOOKUP_NO_CONVERSION (512)
 #define LOOKUP_DESTRUCTOR (512)
 
+/* These flags are used by the conversion code.
+   CONV_IMPLICIT   :  Perform implicit conversions (standard and user-defined).
+   CONV_STATIC     :  Perform the explicit conversions for static_cast.
+   CONV_CONST      :  Perform the explicit conversions for const_cast.
+   CONV_REINTERPRET:  Perform the explicit conversions for reinterpret_cast.
+   CONV_PRIVATE    :  Perform upcasts to private bases.  */
+
+#define CONV_IMPLICIT    1
+#define CONV_STATIC      2
+#define CONV_CONST       4
+#define CONV_REINTERPRET 8
+#define CONV_PRIVATE    16
+#define CONV_STATIC_CAST (CONV_IMPLICIT | CONV_STATIC)
+#define CONV_OLD_CONVERT (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \
+                         | CONV_REINTERPRET)
+#define CONV_C_CAST      (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \
+                         | CONV_REINTERPRET | CONV_PRIVATE)
+
 /* Anatomy of a DECL_FRIENDLIST (which is a TREE_LIST):
    purpose = friend name (IDENTIFIER_NODE);
    value = TREE_LIST of FUNCTION_DECLS;
@@ -1790,7 +1811,7 @@ extern void print_class_statistics                PROTO((void));
 extern void maybe_push_cache_obstack           PROTO((void));
 
 /* in cvt.c */
-extern tree convert_to_reference               PROTO((tree, tree, tree, tree, int, char *, int, int));
+extern tree convert_to_reference               PROTO((tree, tree, int, int, tree));
 extern tree convert_from_reference             PROTO((tree));
 extern tree convert_to_aggr                    PROTO((tree, tree, char **, int));
 extern tree convert_pointer_to                 PROTO((tree, tree));
index b160412..d614c70 100644 (file)
@@ -594,40 +594,29 @@ build_up_reference (type, arg, flags, checkconst)
 /* For C++: Only need to do one-level references, but cannot
    get tripped up on signed/unsigned differences.
 
-   If DECL is NULL_TREE it means convert as though casting (by force).
-   If it is ERROR_MARK_NODE, it means the conversion is implicit,
-   and that temporaries may be created.
-   Make sure the use of user-defined conversion operators is un-ambiguous.
-   Otherwise, DECL is a _DECL node which can be used in error reporting.
+   DECL is either NULL_TREE or the _DECL node for a reference that is being
+   initialized.  It can be error_mark_node if we don't know the _DECL but
+   we know it's an initialization.  */
 
-   FNDECL, PARMNUM, and ERRTYPE are only used when checking for use of
-   volatile or const references where they aren't desired.  */
+tree cp_convert PROTO((tree, tree, int, int));
 
 tree
-convert_to_reference (decl, reftype, expr, fndecl, parmnum,
-                     errtype, strict, flags)
-     tree decl;
+convert_to_reference (reftype, expr, convtype, flags, decl)
      tree reftype, expr;
-     tree fndecl;
-     int parmnum;
-     char *errtype;
-     int strict, flags;
+     int convtype, flags;
+     tree decl;
 {
   register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
   register tree intype = TREE_TYPE (expr);
   register enum tree_code form = TREE_CODE (intype);
   tree rval = NULL_TREE;
 
-#if 0
-  if (TREE_CODE (type) == ARRAY_TYPE)
-    type = build_pointer_type (TREE_TYPE (type));
-#endif
-  
   if (form == REFERENCE_TYPE)
     intype = TREE_TYPE (intype);
   intype = TYPE_MAIN_VARIANT (intype);
 
   if (IS_AGGR_TYPE (intype)
+      && ! (flags & LOOKUP_NO_CONVERSION)
       && (rval = build_type_conversion (CONVERT_EXPR, reftype, expr, 1)))
     {
       if (rval == error_mark_node)
@@ -636,16 +625,11 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
       return rval;
     }
 
-  if (comptypes (type, intype, strict))
+  if (((convtype & CONV_STATIC) && comptypes (type, intype, -1))
+      || ((convtype & CONV_IMPLICIT) && comptypes (type, intype, 0)))
     {
-      /* Section 13.  */
       if (flags & LOOKUP_COMPLAIN)
        {
-         /* Since convert_for_initialization didn't call
-            convert_for_assignment, we have to do this checking here.
-            FIXME: We should have a common routine between here and
-            convert_for_assignment.  */
-
          tree ttl = TREE_TYPE (reftype);
          tree ttr;
          
@@ -654,37 +638,25 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
          else
            ttr = TREE_TYPE (expr);
 
-         if (! TYPE_READONLY (ttl))
+         if (! lvalue_p (expr) &&
+             (decl == NULL_TREE || ! TYPE_READONLY (ttl)))
            {
-             if (TYPE_READONLY (ttr) && decl != NULL_TREE)
-               {
-                 if (fndecl)
-                   cp_pedwarn ("passing `%T' as argument %P of `%D' discards const",
-                               TREE_TYPE (expr), parmnum, fndecl);
-                 else
-                   cp_pedwarn ("%s to `%T' from `%T' discards const",
-                               errtype, reftype, TREE_TYPE (expr));
-               }
-             else if (! lvalue_p (expr))
-               {
-                 /* Ensure semantics of 8.4.3 */
-                 if (fndecl)
-                   cp_pedwarn ("ANSI C++ forbids passing non-lvalue `%T' as argument %P of `%D' into non-const &",
-                               TREE_TYPE (expr), parmnum, fndecl);
-                 else
-                   cp_pedwarn ("ANSI C++ forbids %s to `%T' from non-lvalue `%T'",
-                               errtype, reftype, TREE_TYPE (expr));
-               }
+             if (decl)
+               /* Ensure semantics of [dcl.init.ref] */
+               cp_pedwarn ("initialization of non-const `%T' from rvalue `%T'",
+                           reftype, intype);
+             else
+               cp_pedwarn ("conversion to `%T' from rvalue `%T'",
+                           reftype, intype);
            }
-         else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)
-                  && decl != NULL_TREE)
+         else if (! (convtype & CONV_CONST))
            {
-             if (fndecl)
-               cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
-                           TREE_TYPE (expr), parmnum, fndecl);
-             else
-               cp_pedwarn ("%s to `%T' from `%T' discards volatile",
-                           errtype, reftype, TREE_TYPE (expr));
+             if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
+               cp_pedwarn ("conversion from `%T' to `%T' discards const",
+                           TREE_TYPE (expr), reftype);
+             else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
+               cp_pedwarn ("conversion from `%T' to `%T' discards volatile",
+                           TREE_TYPE (expr), reftype);
            }
        }
       
@@ -718,15 +690,17 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
          rval = build1 (NOP_EXPR,
                         build_pointer_type (TREE_TYPE (TREE_TYPE (expr))),
                         expr);
-         rval = convert (build_pointer_type (TREE_TYPE (reftype)), rval);
+         rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), rval,
+                            convtype, flags);
          rval = build1 (NOP_EXPR, reftype, rval);
          return rval;
        }
 
-      return build_up_reference (reftype, expr, flags, decl!=NULL_TREE);
+      return build_up_reference (reftype, expr, flags,
+                                ! (convtype & CONV_CONST));
     }
 
-  if (decl == NULL_TREE && lvalue_p (expr))
+  if ((convtype & CONV_REINTERPRET) && lvalue_p (expr))
     {
       /* When casting an lvalue to a reference type, just convert into
         a pointer to the new type and deference it.  This is allowed
@@ -736,7 +710,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
       /* B* bp; A& ar = (A&)bp; is legal, but it's probably not what they
          meant.  */
       if (form == POINTER_TYPE
-         && (comptypes (TREE_TYPE (intype), type, strict)))
+         && (comptypes (TREE_TYPE (intype), type, -1)))
        cp_warning ("casting `%T' to `%T' does not dereference pointer",
                    intype, reftype);
          
@@ -746,7 +720,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
       if (rval != error_mark_node)
        rval = build1 (NOP_EXPR, reftype, rval);
     }
-  else if (decl == error_mark_node || decl == NULL_TREE)
+  else if (decl)
     {
       tree rval_as_conversion = NULL_TREE;
       tree rval_as_ctor = NULL_TREE;
@@ -773,23 +747,25 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
          if (global_bindings_p ())
            {
              extern tree static_aggregates;
-             decl = get_temp_name (type, global_bindings_p ());
-             init = build_method_call (decl, constructor_name_full (type),
+             tree t = get_temp_name (type, global_bindings_p ());
+             init = build_method_call (t, constructor_name_full (type),
                                        build_tree_list (NULL_TREE, expr),
-                                       TYPE_BINFO (type), LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+                                       TYPE_BINFO (type),
+                                       LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
 
              if (init == error_mark_node)
                return error_mark_node;
 
-             make_decl_rtl (decl, NULL_PTR, 1);
-             static_aggregates = perm_tree_cons (expr, decl, static_aggregates);
-             rval = build_unary_op (ADDR_EXPR, decl, 0);
+             make_decl_rtl (t, NULL_PTR, 1);
+             static_aggregates = perm_tree_cons (expr, t, static_aggregates);
+             rval = build_unary_op (ADDR_EXPR, t, 0);
            }
          else
            {
              init = build_method_call (NULL_TREE, constructor_name_full (type),
                                        build_tree_list (NULL_TREE, expr),
-                                       TYPE_BINFO (type), LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+                                       TYPE_BINFO (type),
+                                       LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
 
              if (init == error_mark_node)
                return error_mark_node;
@@ -820,8 +796,8 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
        }
 
       if (rval && ! TYPE_READONLY (TREE_TYPE (reftype)))
-       cp_pedwarn ("converting `%T' to non-const `%T' will use a temporary",
-                   intype, reftype);
+       cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary",
+                   reftype, intype);
     }
 
   if (rval)
@@ -1219,15 +1195,10 @@ convert_pointer_to_vbase (binfo, expr)
   return NULL_TREE;
 }
 \f
-/* Create an expression whose value is that of EXPR,
-   converted to type TYPE.  The TREE_TYPE of the value
-   is always TYPE.  This function implements all reasonable
-   conversions; callers should filter out those that are
-   not permitted by the language being compiled.  */
-
 tree
-convert (type, expr)
+cp_convert (type, expr, convtype, flags)
      tree type, expr;
+     int convtype, flags;
 {
   register tree e = expr;
   register enum tree_code code = TREE_CODE (type);
@@ -1235,25 +1206,16 @@ convert (type, expr)
   if (type == TREE_TYPE (expr)
       || TREE_CODE (expr) == ERROR_MARK)
     return expr;
-  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
-    return fold (build1 (NOP_EXPR, type, expr));
   if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
     return error_mark_node;
-  if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
-    {
-      error ("void value not ignored as it ought to be");
-      return error_mark_node;
-    }
-  if (code == VOID_TYPE)
-    {
-      /* We're converting to a void type; see if they have an
-        `operator void'.  */
-      tree rval = build_type_conversion (NOP_EXPR, type, e, 0);
-      /* If we can convert to void type via a type conversion, do so.  */
-      if (rval)
-       return rval;
-      return build1 (CONVERT_EXPR, type, e);
-    }
+
+  /* Trivial conversion: cv-qualifiers do not matter on rvalues.  */
+  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
+    return fold (build1 (NOP_EXPR, type, expr));
+  
+  if (code == VOID_TYPE && (convtype & CONV_STATIC))
+    return build1 (CONVERT_EXPR, type, e);
+
 #if 0
   /* This is incorrect.  A truncation can't be stripped this way.
      Extensions will be stripped by the use of get_unwidened.  */
@@ -1268,10 +1230,8 @@ convert (type, expr)
       code = TREE_CODE (type);
     }
 
-  /* C++ */
   if (code == REFERENCE_TYPE)
-    return fold (convert_to_reference (error_mark_node, type, e, NULL_TREE,
-                                      -1, "conversion", -1, LOOKUP_NORMAL));
+    return fold (convert_to_reference (type, e, convtype, flags, NULL_TREE));
   else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
     e = convert_from_reference (e);
 
@@ -1455,6 +1415,19 @@ convert (type, expr)
   return error_mark_node;
 }
 
+/* Create an expression whose value is that of EXPR,
+   converted to type TYPE.  The TREE_TYPE of the value
+   is always TYPE.  This function implements all reasonable
+   conversions; callers should filter out those that are
+   not permitted by the language being compiled.  */
+
+tree
+convert (type, expr)
+     tree type, expr;
+{
+  return cp_convert (type, expr, CONV_OLD_CONVERT, 0);
+}
+
 /* Like convert, except permit conversions to take place which
    are not normally allowed due to access restrictions
    (such as conversion from sub-type to private super-type).  */
@@ -1467,8 +1440,8 @@ convert_force (type, expr)
   register enum tree_code code = TREE_CODE (type);
 
   if (code == REFERENCE_TYPE)
-    return fold (convert_to_reference (0, type, e, NULL_TREE, -1,
-                                      "casting", -1, LOOKUP_COMPLAIN));
+    return fold (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,
+                                      NULL_TREE));
   else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
     e = convert_from_reference (e);
 
@@ -1539,11 +1512,7 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
       && (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))
          > TREE_READONLY (TREE_TYPE (xtype))))
     warning ("user-defined conversion casting away `const'");
-  rval = convert_for_initialization (NULL_TREE, xtype, rval, flags,
-                                    "conversion", NULL_TREE, 0);
-  if (rval == error_mark_node)
-    return NULL_TREE;
-  return rval;
+  return convert (xtype, rval);
 }
 
 /* Convert an aggregate EXPR to type XTYPE.  If a conversion
index e33db79..1c9905f 100644 (file)
@@ -47,6 +47,8 @@ extern struct obstack permanent_obstack;
 
 extern int current_class_depth;
 
+extern tree cleanups_this_call;
+
 /* Stack of places to restore the search obstack back to.  */
    
 /* Obstack used for remembering local class declarations (like
@@ -1077,7 +1079,7 @@ poplevel (keep, reverse, functionbody)
     }
 
   /* Take care of compiler's internal binding structures.  */
-  if (tmp == 2 && class_binding_level)
+  if (tmp == 2)
     {
 #if 0
       /* We did not call push_momentary for this
@@ -1976,7 +1978,7 @@ decls_match (newdecl, olddecl)
              TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
            }
          else
-           types_match = compparms (p1, p2, 1);
+           types_match = compparms (p1, p2, 3);
        }
       else
        types_match = 0;
@@ -2114,31 +2116,44 @@ duplicate_decls (newdecl, olddecl)
        after implicit decl.  */
     ;
   else if (TREE_CODE (olddecl) == FUNCTION_DECL
-          && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl))
-          && DECL_ASSEMBLER_NAME (newdecl) == DECL_ASSEMBLER_NAME (olddecl))
-    /* Redeclaring a builtin as another function is handled in
-       push_overloaded_decl.  */
+          && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)))
     {
       /* If you declare a built-in or predefined function name as static,
-        the old definition is overridden,
-        but optionally warn this was a bad choice of name.  */
-      if (! TREE_PUBLIC (newdecl))
-       if (warn_shadow)
-         cp_warning ("shadowing %s function `%#D'",
-                     DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                     newdecl);
-      /* Likewise, if the built-in is not ansi, then programs can override
-         it even globally without an error.  */
-      else if (! DECL_BUILT_IN (olddecl))
-       cp_warning ("library function `%#D' redeclared as non-function `%#D'",
-                   olddecl, newdecl);
-      else
+        the old definition is overridden, but optionally warn this was a
+        bad choice of name.  Ditto for overloads.  */
+      if (! TREE_PUBLIC (newdecl)
+         || (TREE_CODE (newdecl) == FUNCTION_DECL
+             && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)))
+       {
+         if (warn_shadow)
+           cp_warning ("shadowing %s function `%#D'",
+                       DECL_BUILT_IN (olddecl) ? "built-in" : "library",
+                       olddecl);
+         /* Discard the old built-in function.  */
+         return 0;
+       }
+      else if (! types_match)
        {
+         if (TREE_CODE (newdecl) != FUNCTION_DECL)
+           {
+             /* If the built-in is not ansi, then programs can override
+                it even globally without an error.  */
+             if (! DECL_BUILT_IN (olddecl))
+               cp_warning ("library function `%#D' redeclared as non-function `%#D'",
+                           olddecl, newdecl);
+             else
+               {
+                 cp_error ("declaration of `%#D'", newdecl);
+                 cp_error ("conflicts with built-in declaration `%#D'",
+                           olddecl);
+               }
+             return 0;
+           }
+
          cp_warning ("declaration of `%#D'", newdecl);
          cp_warning ("conflicts with built-in declaration `%#D'",
                      olddecl);
        }
-      return 0;
     }
   else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
     {
@@ -2185,7 +2200,7 @@ duplicate_decls (newdecl, olddecl)
        }
 
       /* Already complained about this, so don't do so again.  */
-      if (current_class_type == NULL_TREE
+      else if (current_class_type == NULL_TREE
          || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)
        {
          /* Since we're doing this before finish_struct can set the
@@ -3082,7 +3097,12 @@ pushdecl_class_level (x)
             members are checked in finish_struct.  */
          tree icv = IDENTIFIER_CLASS_VALUE (name);
 
-         if (icv)
+         if (icv
+             /* Don't complain about inherited names.  */
+             && id_in_current_class (name)
+             /* Or shadowed tags.  */
+             && !(TREE_CODE (icv) == TYPE_DECL
+                  && DECL_CONTEXT (icv) == current_class_type))
            {
              cp_error ("declaration of identifier `%D' as `%#D'", name, x);
              cp_error_at ("conflicts with previous use in class as `%#D'",
@@ -3186,23 +3206,18 @@ push_overloaded_decl (decl, forgettable)
     {
       old = IDENTIFIER_GLOBAL_VALUE (orig_name);
       if (old && TREE_CODE (old) == FUNCTION_DECL
+         && DECL_ARTIFICIAL (old)
          && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
        {
-         if (! decls_match (decl, old)
-             && (DECL_LANGUAGE (decl) == lang_c
-                 || compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)),
-                               TYPE_ARG_TYPES (TREE_TYPE (old)), 2)))
-           {
-             cp_warning ("declaration of `%#D'", decl);
-             cp_warning ("conflicts with built-in declaration `%#D'", old);
-           }
+         if (duplicate_decls (decl, old))
+           return old;
          old = NULL_TREE;
        }
     }
   else
     {
       old = IDENTIFIER_LOCAL_VALUE (orig_name);
-      
+
       if (! purpose_member (orig_name, current_binding_level->shadowed))
        {
          current_binding_level->shadowed
@@ -3355,6 +3370,18 @@ redeclaration_error_message (newdecl, olddecl)
          else
            return "redefinition of `%#D'";
        }
+
+      {
+       tree t1 = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
+       tree t2 = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
+
+       if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE)
+         t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2);
+       
+       for (; t1; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
+         if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
+           return "duplicate default arguments given for `%#D'";
+      }
       return 0;
     }
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
@@ -3990,9 +4017,19 @@ lookup_name_current_level (name)
     }
   else if (IDENTIFIER_LOCAL_VALUE (name) != NULL_TREE)
     {
-      for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
-       if (DECL_NAME (t) == name)
-         break;
+      struct binding_level *b = current_binding_level;
+      while (1)
+       {
+         for (t = b->names; t; t = TREE_CHAIN (t))
+           if (DECL_NAME (t) == name)
+             goto out;
+         if (b->keep == 2)
+           b = b->level_chain;
+         else
+           break;
+       }
+    out:
+      ;
     }
 
   return t;
@@ -5559,25 +5596,14 @@ grok_reference_init (decl, type, init, cleanupp)
     }
   /* OK, can we generate a reference then?  */
   else if ((actual_init = convert_to_reference
-           (decl, type, init, 0, 0, "initialization", 0,
-            LOOKUP_SPECULATIVELY|LOOKUP_NORMAL)))
+           (type, init, CONV_IMPLICIT,
+            LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl)))
     {
       if (actual_init == error_mark_node)
        goto fail;
 
       init = actual_init;
       is_reference = 1;
-    }
-  /* OK, try going through a temporary.  */
-  else if ((actual_init = convert_to_reference
-           (error_mark_node, type, init, 0, 0, "initialization",
-            0, LOOKUP_NORMAL)))
-    {
-      if (actual_init == error_mark_node)
-       goto fail;
-      
-      init = actual_init;
-      is_reference = 1;
 
       if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
        {
@@ -5705,12 +5731,9 @@ finish_decl (decl, init, asmspec_tree, need_pop)
       return;
     }
 
+  /* If a name was specified, get the string.  */
   if (asmspec_tree)
-    {
       asmspec = TREE_STRING_POINTER (asmspec_tree);
-      /* Zero out old RTL, since we will rewrite it.  */
-      DECL_RTL (decl) = NULL_RTX;
-    }
 
   /* If the type of the thing we are declaring either has
      a constructor, or has a virtual function table pointer,
@@ -6276,6 +6299,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
        }
       else if (! toplev)
        {
+         tree old_cleanups = cleanups_this_call;
          /* This is a declared decl which must live until the
             end of the binding contour.  It may need a cleanup.  */
 
@@ -6335,6 +6359,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
                              decl);
                }
            }
+         /* Cleanup any temporaries needed for the initial value.  */
+         expand_cleanups_to (old_cleanups);
        }
     finish_end0:
 
@@ -6404,6 +6430,8 @@ expand_static_init (decl, init)
      tree init;
 {
   tree oldstatic = value_member (decl, static_aggregates);
+  tree old_cleanups;
+
   if (oldstatic)
     {
       if (TREE_PURPOSE (oldstatic) && init != NULL_TREE)
@@ -6422,6 +6450,7 @@ expand_static_init (decl, init)
       rest_of_decl_compilation (temp, NULL_PTR, 0, 0);
       expand_start_cond (build_binary_op (EQ_EXPR, temp,
                                          integer_zero_node, 1), 0);
+      old_cleanups = cleanups_this_call;
       expand_assignment (temp, integer_one_node, 0, 0);
       if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
        {
@@ -6430,6 +6459,8 @@ expand_static_init (decl, init)
        }
       else
        expand_assignment (decl, init, 0, 0);
+      /* Cleanup any temporaries needed for the initial value.  */
+      expand_cleanups_to (old_cleanups);
       expand_end_cond ();
       if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
        {
@@ -10235,6 +10266,7 @@ finish_enum (enumtype, values)
          else if (value < minvalue)
            minvalue = value;
          TREE_TYPE (TREE_VALUE (pair)) = enumtype;
+         TREE_TYPE (DECL_INITIAL (TREE_VALUE (pair))) = enumtype;
        }
     }
 
@@ -11968,3 +12000,10 @@ revert_static_member_fn (decl, fn, argtypes)
   if (argtypes)
     *argtypes = args;
 }
+
+int
+id_in_current_class (id)
+     tree id;
+{
+  return !!purpose_member (id, class_binding_level->class_shadowed);
+}
index d6eb5d9..c5ab8db 100644 (file)
@@ -37,6 +37,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 extern tree grokdeclarator ();
 extern tree get_file_function_name ();
+extern tree cleanups_this_call;
 static void grok_function_init ();
 
 /* A list of virtual function tables we must make sure to write out.  */
@@ -362,6 +363,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
   {"huge-objects", &flag_huge_objects, 1},
   {"conserve-space", &flag_conserve_space, 1},
   {"vtable-thunks", &flag_vtable_thunks, 1},
+  {"short-temps", &flag_short_temps, 1},
 };
 
 /* Decode the string P as a language-specific option.
@@ -2595,6 +2597,7 @@ finish_file ()
        {
          tree decl = TREE_VALUE (vars);
          tree init = TREE_PURPOSE (vars);
+         tree old_cleanups = cleanups_this_call;
 
          /* If this was a static attribute within some function's scope,
             then don't initialize it here.  Also, don't bother
@@ -2684,6 +2687,8 @@ finish_file ()
            ;
          else my_friendly_abort (22);
          vars = TREE_CHAIN (vars);
+         /* Cleanup any temporaries needed for the initial value.  */
+         expand_cleanups_to (old_cleanups);
        }
 
       expand_end_bindings (getdecls(), 1, 0);
@@ -2936,7 +2941,7 @@ finish_decl_parsing (decl)
       TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
       return decl;
     case SCOPE_REF:
-      push_nested_class (TREE_OPERAND (decl, 0), 3);
+      push_nested_class (TREE_TYPE (TREE_OPERAND (decl, 0)), 3);
       TREE_COMPLEXITY (decl) = current_class_depth;
       return decl;
     case ARRAY_REF:
index 60fd392..160a10b 100644 (file)
@@ -35,11 +35,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 tree builtin_return_address_fndecl;
 
 /* Define at your own risk!  */
+#ifndef CROSS_COMPILE
 #ifdef sun
 #ifdef sparc
 #define TRY_NEW_EH
 #endif
 #endif
+#endif
 
 #ifndef TRY_NEW_EH
 
@@ -97,8 +99,8 @@ expand_end_all_catch ()
 }
 
 void
-expand_start_catch_block (typename, identifier)
-     tree typename, identifier;
+expand_start_catch_block (declspecs, declarator)
+     tree declspecs, declarator;
 {
 }
 
@@ -409,7 +411,6 @@ exception_section ()
 
 extern rtx emit_insn           PROTO((rtx));
 extern rtx gen_nop             PROTO(());
-extern void do_unwind          PROTO((rtx));
 
 /* local globals for function calls
    ====================================================================== */
@@ -808,7 +809,7 @@ init_exception_processing ()
   catch_match_fndecl =
     define_function ("__throw_type_match",
                     build_function_type (integer_type_node,
-                                         tree_cons (NULL_TREE, string_type_node, tree_cons (NULL_TREE, string_type_node, void_list_node))),
+                                         tree_cons (NULL_TREE, string_type_node, tree_cons (NULL_TREE, ptr_type_node, void_list_node))),
                     NOT_BUILT_IN,
                     pushdecl,
                     0);
@@ -1088,24 +1089,27 @@ expand_leftover_cleanups ()
     }
 }
 
-
 /* call this to start a catch block. Typename is the typename, and identifier
    is the variable to place the object in or NULL if the variable doesn't
    matter.  If typename is NULL, that means its a "catch (...)" or catch
    everything.  In that case we don't need to do any type checking.
    (ie: it ends up as the "else" clause rather than an "else if" clause) */
 void
-expand_start_catch_block (typename, identifier)
-     tree typename, identifier;
+expand_start_catch_block (declspecs, declarator)
+     tree declspecs, declarator;
 {
   rtx false_label_rtx;
   tree type;
+  tree decl;
 
   if (! doing_eh (1))
     return;
 
-  if (typename)
-    type = groktypename (typename);
+  if (declspecs)
+    {
+      decl = grokdeclarator (declarator, declspecs, PARM, 0, NULL_TREE);
+      type = TREE_TYPE (decl);
+    }
   else
     type = NULL_TREE;
 
index 33f1d23..a358534 100644 (file)
@@ -35,6 +35,7 @@ char, TYPESPEC, RID_CHAR,
 class, AGGR, RID_CLASS,
 classof, CLASSOF, NORID,
 const, TYPE_QUAL, RID_CONST,
+const_cast, CONST_CAST, NORID,
 continue, CONTINUE, NORID,
 default, DEFAULT, NORID,
 delete, DELETE, NORID,
@@ -61,6 +62,7 @@ private, VISSPEC, RID_PRIVATE,
 protected, VISSPEC, RID_PROTECTED,
 public, VISSPEC, RID_PUBLIC,
 register, SCSPEC, RID_REGISTER,
+reinterpret_cast, REINTERPRET_CAST, NORID,
 return, RETURN, NORID,
 short, TYPESPEC, RID_SHORT,
 signature, AGGR, RID_SIGNATURE /* Extension */,
@@ -68,11 +70,12 @@ signed, TYPESPEC, RID_SIGNED,
 sigof, SIGOF, NORID            /* Extension */,
 sizeof, SIZEOF, NORID,
 static, SCSPEC, RID_STATIC,
+static_cast, STATIC_CAST, NORID,
 struct, AGGR, RID_RECORD,
 switch, SWITCH, NORID,
 this, THIS, NORID,
 throw, THROW, NORID,
-template, TEMPLATE, NORID,
+template, TEMPLATE, RID_TEMPLATE,
 try, TRY, NORID,
 typedef, SCSPEC, RID_TYPEDEF,
 typeof, TYPEOF, NORID,
index 86bc4ca..0780d02 100644 (file)
@@ -1,14 +1,14 @@
 /* C code produced by gperf version 2.5 (GNU C++ version) */
-/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../devo/gcc/cp/gxx.gperf  */
+/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ /deneb/blob/jason/g++/small/devo/gcc/cp/gxx.gperf  */
 /* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf  */
 struct resword { char *name; short token; enum rid rid;};
 
-#define TOTAL_KEYWORDS 80
+#define TOTAL_KEYWORDS 83
 #define MIN_WORD_LENGTH 2
-#define MAX_WORD_LENGTH 13
+#define MAX_WORD_LENGTH 16
 #define MIN_HASH_VALUE 4
-#define MAX_HASH_VALUE 166
-/* maximum key range = 163, duplicates = 0 */
+#define MAX_HASH_VALUE 170
+/* maximum key range = 167, duplicates = 0 */
 
 #ifdef __GNUC__
 inline
@@ -20,19 +20,19 @@ hash (str, len)
 {
   static unsigned char asso_values[] =
     {
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
-     167, 167, 167, 167, 167,   0, 167,  36,   6,  60,
-      17,   0,  16,   5,  41,  38, 167,  11,  22,   7,
-      26,   0,   4, 167,  22,   0,   4,  44,  19,   8,
-       5,  18, 167, 167, 167, 167, 167, 167,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+     171, 171, 171, 171, 171,   0, 171,  62,   5,  65,
+      27,   0,  18,   7,  10,  48, 171,   1,  30,   7,
+      79,   0,  33, 171,  18,   0,   4,  26,  13,   0,
+       1,  24, 171, 171, 171, 171, 171, 171,
     };
   register int hval = len;
 
@@ -68,103 +68,117 @@ is_reserved_word (str, len)
       {"",}, {"",}, 
       {"__asm__",  GCC_ASM_KEYWORD, NORID},
       {"this",  THIS, NORID,},
-      {"goto",  GOTO, NORID,},
+      {"throw",  THROW, NORID,},
       {"__headof__",  HEADOF, NORID},
-      {"",}, 
+      {"goto",  GOTO, NORID,},
       {"__asm",  GCC_ASM_KEYWORD, NORID},
       {"__const__",  TYPE_QUAL, RID_CONST},
       {"__volatile",  TYPE_QUAL, RID_VOLATILE},
       {"__const",  TYPE_QUAL, RID_CONST},
       {"__volatile__",  TYPE_QUAL, RID_VOLATILE},
-      {"throw",  THROW, NORID,},
+      {"",}, 
       {"enum",  ENUM, NORID,},
-      {"do",  DO, NORID,},
-      {"template",  TEMPLATE, NORID,},
+      {"static_cast",  STATIC_CAST, NORID,},
+      {"switch",  SWITCH, NORID,},
+      {"",}, {"",}, 
       {"sigof",  SIGOF, NORID          /* Extension */,},
       {"sizeof",  SIZEOF, NORID,},
-      {"delete",  DELETE, NORID,},
+      {"",}, 
       {"__headof",  HEADOF, NORID},
-      {"try",  TRY, NORID,},
+      {"short",  TYPESPEC, RID_SHORT,},
       {"typeof",  TYPEOF, NORID,},
-      {"typeid",  TYPEID, NORID,},
+      {"do",  DO, NORID,},
+      {"",}, 
+      {"try",  TRY, NORID,},
+      {"",}, 
+      {"delete",  DELETE, NORID,},
       {"__typeof__",  TYPEOF, NORID},
+      {"while",  WHILE, NORID,},
+      {"struct",  AGGR, RID_RECORD,},
+      {"typeid",  TYPEID, NORID,},
       {"double",  TYPESPEC, RID_DOUBLE,},
-      {"private",  VISSPEC, RID_PRIVATE,},
-      {"short",  TYPESPEC, RID_SHORT,},
-      {"extern",  SCSPEC, RID_EXTERN,},
-      {"__classof__",  CLASSOF, NORID},
+      {"for",  FOR, NORID,},
       {"",}, 
-      {"while",  WHILE, NORID,},
+      {"__classof__",  CLASSOF, NORID},
+      {"",}, {"",}, 
+      {"operator",  OPERATOR, NORID,},
+      {"",}, {"",}, 
+      {"typedef",  SCSPEC, RID_TYPEDEF,},
       {"long",  TYPESPEC, RID_LONG,},
-      {"new",  NEW, NORID,},
-      {"protected",  VISSPEC, RID_PROTECTED,},
-      {"friend",  SCSPEC, RID_FRIEND,},
-      {"auto",  SCSPEC, RID_AUTO,},
-      {"for",  FOR, NORID,},
+      {"template",  TEMPLATE, RID_TEMPLATE,},
       {"__typeof",  TYPEOF, NORID},
-      {"typedef",  SCSPEC, RID_TYPEDEF,},
-      {"__extension__",  EXTENSION, NORID},
+      {"friend",  SCSPEC, RID_FRIEND,},
+      {"",}, 
+      {"private",  VISSPEC, RID_PRIVATE,},
+      {"",}, 
       {"int",  TYPESPEC, RID_INT,},
-      {"asm",  ASM_KEYWORD, NORID,},
+      {"",}, 
       {"__classof",  CLASSOF, NORID},
       {"__signed__",  TYPESPEC, RID_SIGNED},
-      {"signed",  TYPESPEC, RID_SIGNED,},
-      {"mutable",  SCSPEC, RID_MUTABLE,},
-      {"switch",  SWITCH, NORID,},
-      {"operator",  OPERATOR, NORID,},
+      {"",}, {"",}, 
+      {"headof",  HEADOF, NORID,},
+      {"",}, 
       {"__attribute",  ATTRIBUTE, NORID},
-      {"struct",  AGGR, RID_RECORD,},
+      {"",}, 
       {"__attribute__",  ATTRIBUTE, NORID},
+      {"auto",  SCSPEC, RID_AUTO,},
+      {"",}, 
       {"if",  IF, NORID,},
-      {"void",  TYPESPEC, RID_VOID,},
-      {"break",  BREAK, NORID,},
-      {"__alignof__",  ALIGNOF, NORID},
-      {"__inline",  SCSPEC, RID_INLINE},
-      {"float",  TYPESPEC, RID_FLOAT,},
-      {"__inline__",  SCSPEC, RID_INLINE},
-      {"__signed",  TYPESPEC, RID_SIGNED},
       {"case",  CASE, NORID,},
       {"class",  AGGR, RID_CLASS,},
-      {"",}, 
-      {"__label__",  LABEL, NORID},
-      {"default",  DEFAULT, NORID,},
+      {"void",  TYPESPEC, RID_VOID,},
+      {"asm",  ASM_KEYWORD, NORID,},
+      {"break",  BREAK, NORID,},
       {"const",  TYPE_QUAL, RID_CONST,},
       {"static",  SCSPEC, RID_STATIC,},
-      {"",}, {"",}, 
-      {"__alignof",  ALIGNOF, NORID},
+      {"mutable",  SCSPEC, RID_MUTABLE,},
+      {"protected",  VISSPEC, RID_PROTECTED,},
+      {"",}, {"",}, {"",}, {"",}, 
+      {"new",  NEW, NORID,},
+      {"__signed",  TYPESPEC, RID_SIGNED},
       {"virtual",  SCSPEC, RID_VIRTUAL,},
-      {"union",  AGGR, RID_UNION,},
+      {"extern",  SCSPEC, RID_EXTERN,},
       {"",}, {"",}, {"",}, 
-      {"signature",  AGGR, RID_SIGNATURE       /* Extension */,},
-      {"headof",  HEADOF, NORID,},
-      {"",}, 
-      {"inline",  SCSPEC, RID_INLINE,},
-      {"overload",  OVERLOAD, NORID,},
-      {"",}, 
-      {"volatile",  TYPE_QUAL, RID_VOLATILE,},
-      {"",}, {"",}, {"",}, {"",}, 
+      {"float",  TYPESPEC, RID_FLOAT,},
+      {"",}, {"",}, 
       {"register",  SCSPEC, RID_REGISTER,},
-      {"",}, 
-      {"public",  VISSPEC, RID_PUBLIC,},
+      {"__extension__",  EXTENSION, NORID},
       {"",}, {"",}, 
       {"__wchar_t",  TYPESPEC, RID_WCHAR  /* Unique to ANSI C++ */,},
+      {"",}, {"",}, {"",}, {"",}, 
+      {"__label__",  LABEL, NORID},
+      {"inline",  SCSPEC, RID_INLINE,},
+      {"continue",  CONTINUE, NORID,},
+      {"default",  DEFAULT, NORID,},
+      {"char",  TYPESPEC, RID_CHAR,},
       {"",}, {"",}, 
-      {"return",  RETURN, NORID,},
       {"classof",  CLASSOF, NORID,},
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
       {"unsigned",  TYPESPEC, RID_UNSIGNED,},
-      {"char",  TYPESPEC, RID_CHAR,},
+      {"union",  AGGR, RID_UNION,},
+      {"",}, 
+      {"signed",  TYPESPEC, RID_SIGNED,},
+      {"volatile",  TYPE_QUAL, RID_VOLATILE,},
+      {"signature",  AGGR, RID_SIGNATURE       /* Extension */,},
+      {"overload",  OVERLOAD, NORID,},
+      {"",}, {"",}, {"",}, {"",}, 
+      {"__alignof__",  ALIGNOF, NORID},
+      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"return",  RETURN, NORID,},
+      {"",}, {"",}, {"",}, {"",}, 
+      {"public",  VISSPEC, RID_PUBLIC,},
+      {"reinterpret_cast",  REINTERPRET_CAST, NORID,},
+      {"__alignof",  ALIGNOF, NORID},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"continue",  CONTINUE, NORID,},
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"",}, {"",}, {"",}, 
-      {"dynamic_cast",  DYNAMIC_CAST, NORID,},
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"const_cast",  CONST_CAST, NORID,},
+      {"catch",  CATCH, NORID,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      
-      {"catch",  CATCH, NORID,},
+      {"",}, {"",}, 
+      {"__inline",  SCSPEC, RID_INLINE},
+      {"",}, 
+      {"__inline__",  SCSPEC, RID_INLINE},
+      {"",}, 
+      {"dynamic_cast",  DYNAMIC_CAST, NORID,},
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
index 8e70143..6ce92a3 100644 (file)
@@ -643,7 +643,7 @@ emit_base_init (t, immediately)
          /* member could be, for example, a CONST_DECL for an enumerated
             tag; we don't want to try to initialize that, since it already
             has a value.  */
-         if (TREE_CODE (member) != FIELD_DECL)
+         if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member))
            continue;
 
          name = DECL_NAME (member);
@@ -2087,8 +2087,7 @@ build_offset_ref (cname, name)
 
   if (t == NULL_TREE)
     {
-      cp_error ("`%D' is not a member of type `%T'", name,
-               IDENTIFIER_TYPE_VALUE (cname));
+      cp_error ("`%D' is not a member of type `%T'", name, type);
       return error_mark_node;
     }
 
@@ -2748,7 +2747,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
 
       /* We can call pushdecl here, because the TREE_CHAIN of this
         FUNCTION_DECL is not needed for other purposes.  */
-      decl = pushdecl_top_level (decl);
+      decl = pushdecl (decl);
 
       make_decl_rtl (decl, NULL_PTR, 1);
       add_friend (current_class_type, decl);
index 7c88ba5..22cf0a5 100644 (file)
@@ -662,6 +662,9 @@ init_lex ()
   ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED]));
+  ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
+  SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE],
+                         build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE]));
   /* This is for ANSI C++. */
   ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
index 5288a02..f9bf3f1 100644 (file)
@@ -65,6 +65,7 @@ enum rid
   RID_RAISES,
   RID_AUTO,
   RID_MUTABLE,
+  RID_TEMPLATE,
   RID_SIGNATURE,
   /* Before adding enough to get up to 64, the RIDBIT_* macros
      will have to be changed a little. */
index f46f70a..dd8a96a 100644 (file)
@@ -80,8 +80,6 @@ void yyerror ();
    error message if the user supplies an empty conditional expression.  */
 static char *cond_stmt_keyword;
 
-static int doing_explicit;
-
 /* Nonzero if we have an `extern "C"' acting as an extern specifier.  */
 int have_extern_spec;
 int used_extern_spec;
@@ -153,7 +151,7 @@ empty_parms ()
 %token <itype> VISSPEC
 %token DELETE NEW OVERLOAD THIS OPERATOR
 %token LEFT_RIGHT TEMPLATE
-%token TYPEID DYNAMIC_CAST
+%token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST
 %token <itype> SCOPE
 
 /* Define the operator tokens and their precedences.
@@ -197,7 +195,7 @@ empty_parms ()
 %type <code> unop
 
 %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist
-%type <ttype> optional_identifier paren_expr_or_null nontrivial_exprlist
+%type <ttype> paren_expr_or_null nontrivial_exprlist
 %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
 %type <ttype> typed_declspecs reserved_declspecs
 %type <ttype> typed_typespecs reserved_typespecquals
@@ -242,7 +240,7 @@ empty_parms ()
 %type <ttype> class_head base_class_list
 %type <itype> base_class_access_list
 %type <ttype> base_class maybe_base_class_list base_class.1
-%type <ttype> maybe_raises raise_identifier raise_identifiers ansi_raise_identifier ansi_raise_identifiers
+%type <ttype> maybe_raises ansi_raise_identifier ansi_raise_identifiers
 %type <ttype> component_declarator0
 %type <ttype> forhead.1 operator_name
 %type <ttype> object aggr
@@ -261,7 +259,7 @@ empty_parms ()
 %type <ttype> qualified_type_name complete_type_name notype_identifier
 %type <ttype> complex_type_name nested_name_specifier_1
 %type <itype> nomods_initdecls nomods_initdcl0
-%type <ttype> new_initializer new_placement specialization
+%type <ttype> new_initializer new_placement specialization type_specifier_seq
 
 /* in order to recognize aggr tags as defining and thus shadowing. */
 %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
@@ -538,7 +536,6 @@ datadef:
         | declmods ';'
          { pedwarn ("empty declaration"); }
        | explicit_instantiation ';'
-               { doing_explicit = 0; }
        | typed_declspecs ';'
          {
            tree t = $<ttype>$;
@@ -775,16 +772,11 @@ identifier_defn:
        | PTYPENAME_DEFN
        ;
 
-do_explicit: TEMPLATE %prec EMPTY
-       { doing_explicit = 1; }
-       ;
-
 explicit_instantiation:
-         do_explicit specialization template_instantiation
+         TEMPLATE specialization template_instantiation
                { do_type_instantiation ($3 ? $3 : $2); }
-       | do_explicit typed_declspecs declarator
+       | TEMPLATE typed_declspecs declarator
                { do_function_instantiation ($2, $3); }
-       | do_explicit error
        ;
 
 template_type:
@@ -925,7 +917,7 @@ xcond:
        ;
 
 condition:
-       typed_typespecs declarator maybe_raises maybeasm maybe_attribute '='
+       type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '='
                { {
                  tree d;
                  for (d = getdecls (); d; d = TREE_CHAIN (d))
@@ -953,6 +945,17 @@ condition:
        | expr
        ;
 
+already_scoped_stmt:
+         '{' '}'
+               { finish_stmt (); }
+       | '{' maybe_label_decls stmts '}'
+               { finish_stmt (); }
+       | '{' maybe_label_decls error '}'
+               { finish_stmt (); }
+       | simple_stmt
+       ;
+
+
 nontrivial_exprlist:
          expr_no_commas ',' expr_no_commas
                { $$ = tree_cons (NULL_TREE, $$, 
@@ -1414,10 +1417,18 @@ primary:
                    }
                }
        | functional_cast
-       /* Stroustrup RTTI */
        | DYNAMIC_CAST '<' type_id '>' '(' expr ')'
                { tree type = groktypename ($3);
                  $$ = build_dynamic_cast (type, $6); }
+       | STATIC_CAST '<' type_id '>' '(' expr ')'
+               { tree type = groktypename ($3);
+                 $$ = build_static_cast (type, $6); }
+       | REINTERPRET_CAST '<' type_id '>' '(' expr ')'
+               { tree type = groktypename ($3);
+                 $$ = build_reinterpret_cast (type, $6); }
+       | CONST_CAST '<' type_id '>' '(' expr ')'
+               { tree type = groktypename ($3);
+                 $$ = build_const_cast (type, $6); }
        | TYPEID '(' expr ')'
                { $$ = build_typeid ($3); }
        | TYPEID '(' type_id ')'
@@ -2168,8 +2179,8 @@ specialization:
          aggr template_type_name ';'
                { 
                  yyungetc (';', 1); current_aggr = $$; $$ = $2; 
-                 if (doing_explicit)
-                   instantiate_class_template ($$, 1);
+                 if ($<ttype>0 == ridpointers[(int) RID_TEMPLATE])
+                   instantiate_class_template ($$, 2);
                }
        ;
 
@@ -2644,13 +2655,9 @@ enumerator:
 
 /* ANSI new-type-id (5.3.4) */
 new_type_id:
-         typed_typespecs new_declarator
-               { $$ = build_decl_list ($$, $2); }
-       | nonempty_type_quals new_declarator
+         type_specifier_seq new_declarator
                { $$ = build_decl_list ($$, $2); }
-       | typed_typespecs %prec EMPTY
-               { $$ = build_decl_list ($$, NULL_TREE); }
-       | nonempty_type_quals %prec EMPTY
+       | type_specifier_seq %prec EMPTY
                { $$ = build_decl_list ($$, NULL_TREE); }
        /* GNU extension to allow arrays of arbitrary types with
           non-constant dimension.  */
@@ -3100,7 +3107,7 @@ simple_stmt:
                  cond_stmt_keyword = "while"; }
          .pushlevel paren_cond_or_null
                { expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
-         implicitly_scoped_stmt
+         already_scoped_stmt
                { expand_end_bindings (getdecls (), kept_level_p (), 1);
                  poplevel (kept_level_p (), 1, 0);
                  pop_momentary ();
@@ -3131,14 +3138,14 @@ simple_stmt:
                /* Don't let the tree nodes for $7 be discarded
                   by clear_momentary during the parsing of the next stmt.  */
                { push_momentary (); }
-         implicitly_scoped_stmt
+         already_scoped_stmt
                { emit_line_note (input_filename, lineno);
-                 expand_loop_continue_here ();
-                 if ($7) cplus_expand_expr_stmt ($7);
-                 pop_momentary ();
                  expand_end_bindings (getdecls (), kept_level_p (), 1);
                  poplevel (kept_level_p (), 1, 0);
                  pop_momentary ();
+                 expand_loop_continue_here ();
+                 if ($7) cplus_expand_expr_stmt ($7);
+                 pop_momentary ();
                  expand_end_loop ();
                  finish_stmt (); }
        | forhead.2
@@ -3153,14 +3160,14 @@ simple_stmt:
                   by clear_momentary during the parsing of the next stmt.  */
                { push_momentary ();
                  $<itype>8 = lineno; }
-         implicitly_scoped_stmt
+         already_scoped_stmt
                { emit_line_note (input_filename, (int) $<itype>8);
-                 expand_loop_continue_here ();
-                 if ($7) cplus_expand_expr_stmt ($7);
-                 pop_momentary ();
                  expand_end_bindings (getdecls (), kept_level_p (), 1);
                  poplevel (kept_level_p (), 1, 0);
                  pop_momentary ();
+                 expand_loop_continue_here ();
+                 if ($7) cplus_expand_expr_stmt ($7);
+                 pop_momentary ();
                  expand_end_loop ();
                  finish_stmt ();
                }
@@ -3422,11 +3429,6 @@ ansi_try_stmts:
                }
        ;
 
-optional_identifier:
-         /* empty */
-               { $$ = NULL_TREE; }
-       | identifier ;
-
 handler_seq:
          /* empty */
        | handler_seq CATCH
@@ -3435,10 +3437,21 @@ handler_seq:
                { expand_end_catch_block (); }
        ;
 
+type_specifier_seq:
+         typed_typespecs %prec EMPTY
+       | nonempty_type_quals %prec EMPTY
+       ;
+
 handler_args:
          '(' ELLIPSIS ')'
                { expand_start_catch_block (NULL_TREE, NULL_TREE); }
-       | '(' type_id optional_identifier ')'
+       | '(' type_specifier_seq absdcl ')'
+               { expand_start_catch_block ($2, $3); }
+       | '(' type_specifier_seq ')'
+               { expand_start_catch_block ($2, NULL_TREE); }
+       | '(' type_specifier_seq notype_declarator ')'
+               { expand_start_catch_block ($2, $3); }
+       | '(' typed_typespecs after_type_declarator ')'
                { expand_start_catch_block ($2, $3); }
        ;
 
@@ -3704,33 +3717,11 @@ maybe_raises:
                { $$ = $3; }
        ;
 
-raise_identifier:
-/*       ALL
-               { $$ = void_list_node; } */
-         IDENTIFIER
-               { $$ = build_decl_list (NULL_TREE, $$); }
-       | TYPENAME
-               { $$ = build_decl_list (NULL_TREE, $$); }
-       | global_scope IDENTIFIER
-               { $$ = build_decl_list (NULL_TREE, $2); }
-       | global_scope TYPENAME
-               { $$ = build_decl_list (NULL_TREE, $2); }
-       ;
-
 ansi_raise_identifier:
          type_id
                { $$ = build_decl_list (NULL_TREE, $$); }
        ;
 
-raise_identifiers:
-         raise_identifier
-       | raise_identifiers ',' raise_identifier
-               {
-                 TREE_CHAIN ($3) = $$;
-                 $$ = $3;
-               }
-       ;
-
 ansi_raise_identifiers:
          ansi_raise_identifier
        | ansi_raise_identifiers ',' ansi_raise_identifier
@@ -3825,7 +3816,7 @@ operator_name:
        | operator DELETE '[' ']'
                { $$ = ansi_opname[VEC_DELETE_EXPR]; }
        /* Names here should be looked up in class scope ALSO.  */
-       | operator typed_typespecs conversion_declarator
+       | operator type_specifier_seq conversion_declarator
                { $$ = grokoptypename ($2, $3); }
        | operator error
                { $$ = ansi_opname[ERROR_MARK]; }
index 377d4a7..528bbdd 100644 (file)
@@ -265,12 +265,16 @@ end_template_decl (d1, d2, is_class, defn)
       && DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE)
     {
       tree ctx = DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl));
-      tree tmpl;
+      tree tmpl, t;
       my_friendly_assert (TREE_CODE (ctx) == UNINSTANTIATED_P_TYPE, 266);
       tmpl = UPT_TEMPLATE (ctx);
+      for (t = DECL_TEMPLATE_MEMBERS (tmpl); t; t = TREE_CHAIN (t))
+       if (TREE_PURPOSE (t) == DECL_NAME (decl)
+           && duplicate_decls (decl, TREE_VALUE (t)))
+         goto already_there;
       DECL_TEMPLATE_MEMBERS (tmpl) =
-       perm_tree_cons (DECL_NAME (decl), decl,
-                       DECL_TEMPLATE_MEMBERS (tmpl));
+       perm_tree_cons (DECL_NAME (decl), decl, DECL_TEMPLATE_MEMBERS (tmpl));
+    already_there:
       poplevel (0, 0, 0);
       poplevel (0, 0, 0);
     }
@@ -1459,6 +1463,9 @@ tsubst (t, args, nargs, in_decl)
        layout_type (r);
        return r;
       }
+    case OFFSET_TYPE:
+      return build_offset_type
+       (tsubst (TYPE_OFFSET_BASETYPE (t), args, nargs, in_decl), type);
     case FUNCTION_TYPE:
     case METHOD_TYPE:
       {
@@ -2008,10 +2015,19 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
       if (targs[idx] == arg)
        return 0;
       else if (targs[idx])
-       return 1;
+       {
+         if (TYPE_MAIN_VARIANT (targs[idx]) == TYPE_MAIN_VARIANT (arg))
+           /* allow different parms to have different cv-qualifiers */;
+         else
+           return 1;
+       }
       /* Check for mixed types and values.  */
       if (TREE_CODE (TREE_VEC_ELT (tparms, idx)) != IDENTIFIER_NODE)
        return 1;
+      /* Allow trivial conversions.  */
+      if (TYPE_READONLY (parm) < TYPE_READONLY (arg)
+         || TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
+       return 1;
       targs[idx] = arg;
       return 0;
     case TEMPLATE_CONST_PARM:
@@ -2136,8 +2152,12 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
        return unify (tparms, targs, ntparms, TYPE_PTRMEMFUNC_FN_TYPE (parm),
                      arg, nsubsts);
 
-      /* Unification of something that is not a template fails. (mrs) */
-      return 1;
+      /* Allow trivial conversions.  */
+      if (TYPE_MAIN_VARIANT (parm) != TYPE_MAIN_VARIANT (arg)
+         || TYPE_READONLY (parm) < TYPE_READONLY (arg)
+         || TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
+       return 1;
+      return 0;
 
     case METHOD_TYPE:
       if (TREE_CODE (arg) != METHOD_TYPE)
@@ -2150,7 +2170,16 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
      check_args:
       return type_unification (tparms, targs, TYPE_ARG_TYPES (parm),
                               TYPE_ARG_TYPES (arg), nsubsts, 1);
-                   
+
+    case OFFSET_TYPE:
+      if (TREE_CODE (arg) != OFFSET_TYPE)
+       return 1;
+      if (unify (tparms, targs, ntparms, TYPE_OFFSET_BASETYPE (parm),
+                TYPE_OFFSET_BASETYPE (arg), nsubsts))
+       return 1;
+      return unify (tparms, targs, ntparms, TREE_TYPE (parm),
+                   TREE_TYPE (arg), nsubsts);
+
     default:
       sorry ("use of `%s' in template type unification",
             tree_code_name [(int) TREE_CODE (parm)]);
index 946763c..c81f1e1 100644 (file)
@@ -1134,7 +1134,7 @@ lookup_field (xbasetype, name, protect, want_type)
 
       if (errstr && protect)
        {
-         error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
+         cp_error (errstr, name, type);
          return error_mark_node;
        }
       return rval;
index edb0b78..d8df8e4 100644 (file)
@@ -94,9 +94,6 @@ lvalue_p (ref)
          return (lvalue_p (TREE_OPERAND (ref, 1))
                  && lvalue_p (TREE_OPERAND (ref, 2)));
 
-       case MODIFY_EXPR:
-         return 1;
-
        case COMPOUND_EXPR:
          return lvalue_p (TREE_OPERAND (ref, 1));
        }
index 03ca722..490d998 100644 (file)
@@ -47,7 +47,6 @@ static tree pointer_int_sum ();
 static tree pointer_diff ();
 static tree convert_sequence ();
 /* static */ tree unary_complex_lvalue ();
-static void pedantic_lvalue_warning ();
 tree truthvalue_conversion ();
 
 extern rtx original_result_rtx;
@@ -223,10 +222,7 @@ commonparms (p1, p2)
          if (cmp < 0)
            my_friendly_abort (111);
          if (cmp == 0)
-           {
-             error ("redeclaration of default argument %d", i+1);
-             any_change = 1;
-           }
+           any_change = 1;
          TREE_PURPOSE (n) = TREE_PURPOSE (p2);
        }
       if (TREE_VALUE (p1) != TREE_VALUE (p2))
@@ -411,7 +407,7 @@ common_type (t1, t2)
       return t1;
 
     case METHOD_TYPE:
-      if (TYPE_METHOD_BASETYPE (t1) == TYPE_METHOD_BASETYPE (t2)
+      if (comptypes (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2), 1)
          && TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))
        {
          /* Get this value the long way, since TYPE_METHOD_BASETYPE
@@ -642,6 +638,9 @@ comptypes (type1, type2, strict)
 
     case TEMPLATE_TYPE_PARM:
       return 1;
+
+    case UNINSTANTIATED_P_TYPE:
+      return UPT_TEMPLATE (t1) == UPT_TEMPLATE (t2);
     }
   return 0;
 }
@@ -1340,9 +1339,10 @@ build_object_ref (datum, basetype, field)
   else if (is_aggr_typedef (basetype, 1))
     {
       tree real_basetype = IDENTIFIER_TYPE_VALUE (basetype);
-      if (binfo_or_else (real_basetype, TREE_TYPE (datum)))
+      tree binfo = binfo_or_else (real_basetype, TREE_TYPE (datum));
+      if (binfo)
        return build_component_ref (build_scoped_ref (datum, basetype),
-                                   field, NULL_TREE, 1);
+                                   field, binfo, 1);
     }
   return error_mark_node;
 }
@@ -3006,12 +3006,14 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
            ;
          else if (tt0 == void_type_node)
            {
-             if (pedantic && TREE_CODE (tt1) == FUNCTION_TYPE)
+             if (pedantic && TREE_CODE (tt1) == FUNCTION_TYPE
+                 && tree_int_cst_lt (TYPE_SIZE (type0), TYPE_SIZE (type1)))
                pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer");
            }
          else if (tt1 == void_type_node)
            {
-             if (pedantic && TREE_CODE (tt0) == FUNCTION_TYPE)
+             if (pedantic && TREE_CODE (tt0) == FUNCTION_TYPE
+                 && tree_int_cst_lt (TYPE_SIZE (type1), TYPE_SIZE (type0)))
                pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer");
            }
          else if ((TYPE_SIZE (tt0) != 0) != (TYPE_SIZE (tt1) != 0))
@@ -3457,13 +3459,6 @@ pointer_int_sum (resultcode, ptrop, intop)
 
   register tree result_type = TREE_TYPE (ptrop);
 
-  /* Needed to make OOPS V2R3 work.  */
-  intop = folded;
-  if (TREE_CODE (intop) == INTEGER_CST
-      && TREE_INT_CST_LOW (intop) == 0
-      && TREE_INT_CST_HIGH (intop) == 0)
-    return ptrop;
-
   if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
     {
       if (pedantic || warn_pointer_arith)
@@ -3491,6 +3486,13 @@ pointer_int_sum (resultcode, ptrop, intop)
   else
     size_exp = size_in_bytes (TREE_TYPE (result_type));
 
+  /* Needed to make OOPS V2R3 work.  */
+  intop = folded;
+  if (TREE_CODE (intop) == INTEGER_CST
+      && TREE_INT_CST_LOW (intop) == 0
+      && TREE_INT_CST_HIGH (intop) == 0)
+    return ptrop;
+
   /* If what we are about to multiply by the size of the elements
      contains a constant term, apply distributive law
      and multiply that constant term separately.
@@ -3882,7 +3884,6 @@ build_unary_op (code, xarg, noconvert)
          case FIX_CEIL_EXPR:
            {
              tree incremented, modify, value;
-             pedantic_lvalue_warning (CONVERT_EXPR);
              arg = stabilize_reference (arg);
              if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
                value = arg;
@@ -4158,17 +4159,18 @@ unary_complex_lvalue (code, arg)
   if (TREE_CODE (arg) == COMPOUND_EXPR)
     {
       tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
-      pedantic_lvalue_warning (COMPOUND_EXPR);
       return build (COMPOUND_EXPR, TREE_TYPE (real_result),
                    TREE_OPERAND (arg, 0), real_result);
     }
 
   /* Handle (a ? b : c) used as an "lvalue".  */
   if (TREE_CODE (arg) == COND_EXPR)
-    {
-      pedantic_lvalue_warning (COND_EXPR);
-      return rationalize_conditional_expr (code, arg);
-    }
+    return rationalize_conditional_expr (code, arg);
+
+  if (TREE_CODE (arg) == MODIFY_EXPR)
+    return unary_complex_lvalue
+      (code, build (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (arg, 0)),
+                   arg, TREE_OPERAND (arg, 0)));
 
   if (code != ADDR_EXPR)
     return 0;
@@ -4295,19 +4297,6 @@ unary_complex_lvalue (code, arg)
   /* Don't let anything else be handled specially.  */
   return 0;
 }
-
-/* If pedantic, warn about improper lvalue.   CODE is either COND_EXPR
-   COMPOUND_EXPR, or CONVERT_EXPR (for casts).  */
-
-static void
-pedantic_lvalue_warning (code)
-     enum tree_code code;
-{
-  if (pedantic)
-    pedwarn ("ANSI C++ forbids use of %s expressions as lvalues",
-            code == COND_EXPR ? "conditional"
-            : code == COMPOUND_EXPR ? "compound" : "cast");
-}
 \f
 /* Mark EXP saying that we need to be able to take the
    address of it; it should not be allocated in a register.
@@ -4785,6 +4774,24 @@ build_compound_expr (list)
                break_out_cleanups (TREE_VALUE (list)), rest);
 }
 
+tree build_static_cast (type, expr)
+   tree type, expr;
+{
+  return build_c_cast (type, expr);
+}
+
+tree build_reinterpret_cast (type, expr)
+   tree type, expr;
+{
+  return build_c_cast (type, expr);
+}
+
+tree build_const_cast (type, expr)
+   tree type, expr;
+{
+  return build_c_cast (type, expr);
+}
+
 /* Build an expression representing a cast to type TYPE of expression EXPR.  */
 
 tree
@@ -5294,7 +5301,6 @@ build_modify_expr (lhs, modifycode, rhs)
 
       /* Handle (a, b) used as an "lvalue".  */
     case COMPOUND_EXPR:
-      pedantic_lvalue_warning (COMPOUND_EXPR);
       newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
                                  modifycode, rhs);
       if (TREE_CODE (newrhs) == ERROR_MARK)
@@ -5302,9 +5308,14 @@ build_modify_expr (lhs, modifycode, rhs)
       return build (COMPOUND_EXPR, lhstype,
                    TREE_OPERAND (lhs, 0), newrhs);
 
+    case MODIFY_EXPR:
+      newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs);
+      if (TREE_CODE (newrhs) == ERROR_MARK)
+       return error_mark_node;
+      return build (COMPOUND_EXPR, lhstype, lhs, newrhs);
+
       /* Handle (a ? b : c) used as an "lvalue".  */
     case COND_EXPR:
-      pedantic_lvalue_warning (COND_EXPR);
       rhs = save_expr (rhs);
       {
        /* Produce (a ? (b = rhs) : (c = rhs))
@@ -5450,7 +5461,7 @@ build_modify_expr (lhs, modifycode, rhs)
                                             convert (lhstype, newrhs)));
        if (TREE_CODE (result) == ERROR_MARK)
          return result;
-       return convert (TREE_TYPE (lhs), result);
+       return convert_force (TREE_TYPE (lhs), result);
       }
     }
 
@@ -6559,9 +6570,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
      return here before checking if RHS is of complete type.  */
      
   if (codel == REFERENCE_TYPE)
-    return convert_to_reference ((exp ? exp : error_mark_node),
-                                type, rhs, fndecl, parmnum, errtype,
-                                0, flags);
+    return convert_to_reference (type, rhs, CONV_IMPLICIT, flags,
+                                exp ? exp : error_mark_node);
 
   rhs = require_complete_type (rhs);
   if (rhs == error_mark_node)
index 53106b2..858896a 100644 (file)
@@ -59,7 +59,7 @@ binfo_or_else (parent_or_type, type)
 {
   tree binfo;
   if (TYPE_MAIN_VARIANT (parent_or_type) == TYPE_MAIN_VARIANT (type))
-    return parent_or_type;
+    return TYPE_BINFO (parent_or_type);
   if ((binfo = get_binfo (parent_or_type, TYPE_MAIN_VARIANT (type), 0)))
     {
       if (binfo == error_mark_node)
@@ -738,7 +738,10 @@ digest_init (type, init, tail)
              return error_mark_node;
            }
 
-         if (pedantic && typ1 != char_type_node)
+         if (pedantic
+             && typ1 != char_type_node
+             && typ1 != signed_char_type_node
+             && typ1 != unsigned_char_type_node)
            pedwarn ("ANSI C++ forbids string initializer except for `char' elements");
          TREE_TYPE (string) = type;
          if (TYPE_DOMAIN (type) != 0
@@ -752,7 +755,7 @@ digest_init (type, init, tail)
                 counted in the length of the constant, but in C++ this would
                 be invalid.  */
              if (size < TREE_STRING_LENGTH (string))
-               warning ("initializer-string for array of chars is too long");
+               pedwarn ("initializer-string for array of chars is too long");
            }
          return string;
        }