OSDN Git Service

90th Cygnus<->FSF quick merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Nov 1996 19:49:48 +0000 (19:49 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Nov 1996 19:49:48 +0000 (19:49 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@13141 138bc75d-0d04-0410-961f-82ee72b054a4

17 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/error.c
gcc/cp/lang-options.h
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index b5cf22a..a5cd339 100644 (file)
@@ -1,3 +1,112 @@
+Tue Nov 12 08:39:17 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+        * decl.c (cp_finish_decl): In MINIMAL_PARSE_MODE, only try to use
+        the DECL_VINDEX of DECL if it's set.
+
+        * tree.c (mapcar): Handle RTL_EXPR.
+
+Mon Nov 11 13:57:31 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (current_template_args): New fn.
+       (push_template_decl): Use it.
+       * decl.c (grokdeclarator): Use it.
+
+       * decl2.c (build_expr_from_tree): Dereference ref vars.
+
+       * decl.c (grokdeclarator): Generalize handling of TYPENAME_TYPEs in
+       the decl-specifier-seq.
+
+       * decl.c (grok_op_properties): Don't force the type of a conversion
+       op to be complete.  Don't warn about converting to the same type
+       for template instantiations.
+
+       * decl2.c (finish_file): Don't call instantiate_decl on synthesized
+       methods.
+
+Mon Nov 11 13:20:34 1996  Bob Manson  <manson@charmed.cygnus.com>
+
+       * typeck.c (get_delta_difference): Remove previous bogusness.
+       Don't give errors if force is set.
+
+Fri Nov  8 17:38:44 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl2.c (finish_file): Don't emit debug info.
+       * decl.c (start_function): Call note_debug_info_needed for context.
+       (start_decl): Likewise.
+       (cp_finish_decl): Not here.
+       (finish_function): Or here.
+       (pushdecl): Lose obsolete code.
+       (grokdeclarator): Still do the long long thing after complaining.
+       (finish_enum): Don't call rest_of_type_compilation
+       for DWARF.
+       * class.c (finish_struct_1): Don't call rest_of_type_compilation
+       for DWARF.
+       * search.c (dfs_debug_mark): For DWARF, just call
+       rest_of_type_compilation.
+       (note_debug_info_needed): Don't do anything if we're in a template.
+       * parse.y (named_complex_class_head_sans_basetype): Likewise.
+       * method.c (synthesize_method): For non-local classes,
+       push_to_top_level first.
+
+Fri Nov  8 11:52:28 1996  Bob Manson  <manson@charmed.cygnus.com>
+
+       * typeck.c (get_delta_difference): Add no_error parameter.
+       (build_ptrmemfunc): Call get_delta_difference with no_error set;
+       we don't want error messages when converting unrelated
+       pointer-to-member functions.
+
+Thu Nov  7 11:16:24 1996  Mike Stump  <mrs@cygnus.com>
+
+       * error.c (dump_expr): Improve the wording on error messages that
+       involve pointer to member functions.
+
+Tue Nov  5 17:12:05 1996  Mike Stump  <mrs@cygnus.com>
+
+       * cvt.c (cp_convert_to_pointer): Move code for conversions from
+       (::*)() to void* or (*)() up a bit, so that we can convert from
+       METHOD_TYPEs as well.
+
+Tue Nov  5 14:54:17 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * rtti.c (get_tinfo_fn): Make sure 'type' is permanent.
+       There are no 'member' types.
+       (get_tinfo_fn_dynamic): Diagnose typeid of overloaded fn.
+       (build_x_typeid): Handle errors.
+
+Mon Nov  4 17:43:12 1996  Mike Stump  <mrs@cygnus.com>
+
+       * typeck.c (convert_for_assignment): Handle anachronistic implicit
+       conversions from (::*)() to void* or (*)().
+       * cvt.c (cp_convert_to_pointer): Likewise.
+       (cp_convert_to_pointer_force): Remove cp_convert_to_pointer
+       conversions from here.
+       * decl2.c (lang_decode_option): Add -W{no-,}pmf-conversions.
+       * lang-options.h: Likewise.
+       * decl2.c (warn_pmf2ptr): Define.
+       * cp-tree.h: Declare it.
+       * typeck2.c (digest_init): Allow pmfs down into
+       convert_for_initialization.
+
+Sun Nov  3 09:43:00 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck.c (c_expand_return): Fix for returning overloaded fn.
+
+Fri Nov  1 08:53:17 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * cp-tree.h (DIRECT_BIND): Change from INDIRECT_BIND.
+       * decl.c (grok_reference_init): Pass DIRECT_BIND.
+       * cvt.c (build_up_reference): Don't mark 'this' addressable.  Use
+       DIRECT_BIND.
+       * call.c (convert_like): Don't pass INDIRECT_BIND.
+       * typeck.c (convert_arguments): Likewise.
+       * typeck.c (mark_addressable): Allow &this if flag_this_is_variable.
+
+Thu Oct 31 17:08:49 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck.c (mark_addressable): Support TARGET_EXPR, unify with
+       similar code in build_up_ref.
+       * cvt.c (build_up_reference): Drastically simplify.
+
 Mon Oct 28 12:45:05 1996  Jeffrey A Law  (law@cygnus.com)
 
        * typeck.c (signed_or_unsigned_type): If the given type already
index 80258c0..576ed3a 100644 (file)
@@ -4900,7 +4900,7 @@ convert_like (convs, expr)
     case REF_BIND:
       return convert_to_reference
        (TREE_TYPE (convs), expr,
-        CONV_IMPLICIT, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION|INDIRECT_BIND,
+        CONV_IMPLICIT, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
         error_mark_node);
     case LVALUE_CONV:
       return decay_conversion (expr);
index 28391dc..356c9ca 100644 (file)
@@ -873,7 +873,7 @@ modify_vtable_entry (old_entry_in_list, new_entry, fndecl)
     }
 }
 
-/* Access the virtual function table entry i.  VIRTUALS is the virtual
+/* Access the virtual function table entry N.  VIRTUALS is the virtual
    function table's initializer.  */
 
 static tree
@@ -4188,7 +4188,10 @@ finish_struct_1 (t, warn_anon)
         For example, if a member function is seen and we decide to
         write out that member function, then we can change the value
         of the DECL_IGNORED_P slot, and the type will be output when
-        that member function's debug info is written out.  */
+        that member function's debug info is written out.
+
+        We can't do this with DWARF, which does not support name
+        references between translation units.  */
       if (CLASSTYPE_METHOD_VEC (t))
        {
          extern tree pending_vtables;
@@ -4209,10 +4212,10 @@ finish_struct_1 (t, warn_anon)
        }
       else if (CLASSTYPE_INTERFACE_ONLY (t))
        TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
-    }
 
-  /* Finish debugging output for this type.  */
-  rest_of_type_compilation (t, toplevel_bindings_p ());
+      /* Finish debugging output for this type.  */
+      rest_of_type_compilation (t, toplevel_bindings_p ());
+    }
 
   return t;
 }
index 4326491..f9f76a3 100644 (file)
@@ -243,6 +243,11 @@ extern int warn_format;
 
 extern int warn_nonvdtor;
 
+/* Non-zero means warn when we convert a pointer to member function
+   into a pointer to (void or function).  */
+
+extern int warn_pmf2ptr;
+
 /* Non-zero means warn when a function is declared extern and later inline.  */
 extern int warn_extern_inline;
 
@@ -1845,9 +1850,9 @@ extern tree current_class_type;   /* _TYPE: the type of the current class */
    LOOKUP_HAS_IN_CHARGE means that the "in charge" variable is already
      in the parameter list.
    LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried.
-   INDIRECT_BIND means that if a temporary is created, it should be created so
-     that it lives only as long as WITH_CLEANUP_EXPRs live, else if a temporary
-     is created then it should live as long as the current variable bindings.
+   DIRECT_BIND means that if a temporary is created, it should be created so
+     that it lives as long as the current variable bindings; otherwise it
+     only lives until the end of the complete-expression.
    LOOKUP_SPECULATIVELY means return NULL_TREE if we cannot find what we are
      after.  Note, LOOKUP_COMPLAIN is checked and error messages printed
      before LOOKUP_SPECULATIVELY is checked.
@@ -1865,7 +1870,7 @@ extern tree current_class_type;   /* _TYPE: the type of the current class */
 #define LOOKUP_HAS_IN_CHARGE (32)
 #define LOOKUP_SPECULATIVELY (64)
 #define LOOKUP_ONLYCONVERTING (128)
-#define INDIRECT_BIND (256)
+#define DIRECT_BIND (256)
 #define LOOKUP_NO_CONVERSION (512)
 #define LOOKUP_DESTRUCTOR (512)
 #define LOOKUP_NO_TEMP_BIND (1024)
@@ -2290,6 +2295,7 @@ extern void begin_template_parm_list              PROTO((void));
 extern tree process_template_parm              PROTO((tree, tree));
 extern tree end_template_parm_list             PROTO((tree));
 extern void end_template_decl                  PROTO((void));
+extern tree current_template_args              PROTO((void));
 extern void push_template_decl                 PROTO((tree));
 extern tree lookup_template_class              PROTO((tree, tree, tree));
 extern int uses_template_parms                 PROTO((tree));
index cd40b9a..68b3d6c 100644 (file)
@@ -154,6 +154,50 @@ cp_convert_to_pointer (type, expr)
   if (TYPE_PTRMEMFUNC_P (intype))
     intype = TYPE_PTRMEMFUNC_FN_TYPE (intype);
 
+  /* Handle anachronistic conversions from (::*)() to void* or (*)().  */
+  if (TREE_CODE (type) == POINTER_TYPE
+      && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
+         || TREE_TYPE (type) == void_type_node))
+    {
+      /* Allow an implicit this pointer for pointer to member
+        functions.  */
+      if (TREE_CODE (intype) == POINTER_TYPE
+         && TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE)
+       {
+         tree decl, basebinfo;
+         tree fntype = TREE_TYPE (intype);
+         tree t = TYPE_METHOD_BASETYPE (fntype);
+
+         if (current_class_type == 0
+             || get_base_distance (t, current_class_type, 0, &basebinfo)
+             == -1)
+           {
+             decl = build1 (NOP_EXPR, t, error_mark_node);
+           }
+         else if (current_class_ptr == 0)
+           decl = build1 (NOP_EXPR, t, error_mark_node);
+         else
+           decl = current_class_ref;
+
+         expr = build (OFFSET_REF, fntype, decl, expr);
+       }
+
+      if (TREE_CODE (expr) == OFFSET_REF
+         && TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
+       expr = resolve_offset_ref (expr);
+      if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
+       expr = build_addr_func (expr);
+      if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+       {
+         if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE)
+           if (pedantic || warn_pmf2ptr)
+             cp_pedwarn ("converting from `%T' to `%T'", TREE_TYPE (expr),
+                         type);
+         return build1 (NOP_EXPR, type, expr);
+       }
+      intype = TREE_TYPE (expr);
+    }
+
   form = TREE_CODE (intype);
 
   if (form == POINTER_TYPE || form == REFERENCE_TYPE)
@@ -282,44 +326,6 @@ convert_to_pointer_force (type, expr)
       form = TREE_CODE (intype);
     }
 
-  if (TREE_CODE (type) == POINTER_TYPE
-      && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
-    {
-      /* Allow an implicit this pointer for pointer to member
-         functions.  */
-      if (TYPE_PTRMEMFUNC_P (intype))
-       {
-         tree decl, basebinfo;
-         tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype));
-         tree t = TYPE_METHOD_BASETYPE (fntype);
-
-         if (current_class_type == 0
-             || get_base_distance (t, current_class_type, 0, &basebinfo) == -1)
-           {
-             decl = build1 (NOP_EXPR, t, error_mark_node);
-           }
-         else if (current_class_ptr == 0)
-           decl = build1 (NOP_EXPR, t, error_mark_node);
-         else
-           decl = current_class_ref;
-
-         expr = build (OFFSET_REF, fntype, decl, expr);
-         intype = TREE_TYPE (expr);
-       }
-
-      if (TREE_CODE (expr) == OFFSET_REF && TREE_CODE (intype) == METHOD_TYPE)
-       expr = resolve_offset_ref (expr);
-      if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
-       expr = build_addr_func (expr);
-      if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
-       {
-         if (pedantic
-             && TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE)
-           cp_pedwarn ("cannot convert `%T' to `%T'", intype, type);
-         return build1 (NOP_EXPR, type, expr);
-       }
-    }
-
   if (form == POINTER_TYPE)
     {
       intype = TYPE_MAIN_VARIANT (intype);
@@ -355,7 +361,6 @@ convert_to_pointer_force (type, expr)
            }
          return build_vbase_path (code, type, expr, path, 0);
        }
-      return build1 (NOP_EXPR, type, expr);
     }
 
   return cp_convert_to_pointer (type, expr);
@@ -366,7 +371,7 @@ convert_to_pointer_force (type, expr)
    value we have to begin with is in ARG.
 
    FLAGS controls how we manage access checking.
-   INDIRECT_BIND in FLAGS controls how any temporarys are generated.
+   DIRECT_BIND in FLAGS controls how any temporarys are generated.
    CHECKCONST controls if we report error messages on const subversion.  */
 
 static tree
@@ -512,72 +517,20 @@ build_up_reference (type, arg, flags, checkconst)
         but complain if we need a reference to something declared
         as `register'.  */
 
-    case RESULT_DECL:
-      if (staticp (targ))
-       literal_flag = 1;
-      TREE_ADDRESSABLE (targ) = 1;
-      put_var_into_stack (targ);
-      break;
-
     case PARM_DECL:
-#if 0
-      if (targ == current_class_ptr)
-       {
-         error ("address of `this' not available");
-/* #if 0 */      
-         /* This code makes the following core dump the compiler on a sun4,
-            if the code below is used.
-
-            class e_decl;
-            class a_decl;
-            typedef a_decl* a_ref;
-
-            class a_s {
-            public:
-              a_s();
-              void* append(a_ref& item);
-            };
-            class a_decl {
-            public:
-              a_decl (e_decl *parent);
-              a_s  generic_s;
-              a_s  decls;
-              e_decl* parent;
-            };
-
-            class e_decl {
-            public:
-              e_decl();
-              a_s implementations;
-            };
-
-            void foobar(void *);
-
-            a_decl::a_decl(e_decl *parent) {
-              parent->implementations.append(this);
-            }
-          */
-
-         TREE_ADDRESSABLE (targ) = 1; /* so compiler doesn't die later */
-         put_var_into_stack (targ);
-         break;
-/* #else */
-         return error_mark_node;
-/* #endif */     
-       }
-#endif
-      /* Fall through.  */
+      /* 'this' is not an lvalue.  */
+      if (targ == current_class_ptr && ! flag_this_is_variable)
+       break;
+
+    case RESULT_DECL:
     case VAR_DECL:
     case CONST_DECL:
-      if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ)
-         && !DECL_ARTIFICIAL (targ))
-       cp_warning ("address needed to build reference for `%D', which is declared `register'",
-                   targ);
-      else if (staticp (targ))
+      if (staticp (targ))
        literal_flag = 1;
 
-      TREE_ADDRESSABLE (targ) = 1;
-      put_var_into_stack (targ);
+      /* Fall through.  */
+    case TARGET_EXPR:
+      mark_addressable (targ);
       break;
 
     case COMPOUND_EXPR:
@@ -632,75 +585,30 @@ build_up_reference (type, arg, flags, checkconst)
       TREE_REFERENCE_EXPR (rval) = 1;
       return rval;
 
-    case TARGET_EXPR:
-      TREE_ADDRESSABLE (targ) = 1;
-      put_var_into_stack (TREE_OPERAND (targ, 0));
-      break;
-
     default:
       break;
     }
 
-  if (TREE_ADDRESSABLE (targ) == 0)
+  if ((flags&DIRECT_BIND)
+      && ! real_lvalue_p (targ))
     {
-      if (! (flags&INDIRECT_BIND)
-         && toplevel_bindings_p ())
+      if (toplevel_bindings_p ())
        {
-         tree temp = get_temp_name (argtype, 0);
-         /* Give this new temp some rtl and initialize it.  */
-         DECL_INITIAL (temp) = targ;
-         TREE_STATIC (temp) = 1;
-         cp_finish_decl (temp, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
-         /* Do this after declaring it static.  */
-         rval = build_unary_op (ADDR_EXPR, temp, 0);
-         TREE_TYPE (rval) = type;
-         literal_flag = TREE_CONSTANT (rval);
-         goto done;
-       }
-
-      if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
-       {
-         arg = build_cplus_new (argtype, targ);
-       }
-      else if (flags&INDIRECT_BIND)
-       {
-         /* This should be the default, not the below code.  */
-         /* All callers except grok_reference_init should probably
-             use INDIRECT_BIND.  */
-         tree slot = build (VAR_DECL, argtype);
-         layout_decl (slot, 0);
-         arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
+         arg = get_temp_name (argtype, 1);
+         literal_flag = 1;
        }
       else
        {
-         tree temp = get_temp_name (argtype, 0);
-         rval = build_unary_op (ADDR_EXPR, temp, 0);
-         if (binfo && !BINFO_OFFSET_ZEROP (binfo))
-           rval = convert_pointer_to (target_type, rval);
-         else
-           TREE_TYPE (rval) = type;
-
-         temp = build (MODIFY_EXPR, argtype, temp, arg);
-         TREE_SIDE_EFFECTS (temp) = 1;
-         return build (COMPOUND_EXPR, type, temp, rval);
+         arg = pushdecl (build_decl (VAR_DECL, NULL_TREE, argtype));
+         DECL_ARTIFICIAL (arg) = 1;
        }
+      DECL_INITIAL (arg) = targ;
+      cp_finish_decl (arg, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
     }
-
-  if (! (flags&INDIRECT_BIND))
+  else if (TREE_ADDRESSABLE (targ) == 0 && !(flags&DIRECT_BIND))
     {
-      if (TREE_CODE (arg) == TARGET_EXPR)
-       {
-         tree decl = TREE_OPERAND (arg, 0);
-         tree cleanup;
-
-         if (! toplevel_bindings_p () && ! DECL_RTL (decl))
-           {
-             expand_decl (decl);
-             cleanup = maybe_build_cleanup (decl);
-             if (cleanup)
-               expand_decl_cleanup (decl, cleanup);
-           }
-       }
+      tree slot = build_decl (VAR_DECL, NULL_TREE, argtype);
+      arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
     }
 
   rval = build1 (ADDR_EXPR, type, arg);
index 7c8c28b..dbb2a90 100644 (file)
@@ -3085,20 +3085,6 @@ pushdecl (x)
               if (global_bindings_p ())
                 TYPE_NAME (type) = x;
            }
-         else
-           {
-             tree tname = DECL_NAME (name);
-
-             /* This is a disgusting kludge for dealing with UPTs.  */
-             if (global_bindings_p () && ANON_AGGRNAME_P (tname))
-               {
-                 /* do gratuitous C++ typedefing, and make sure that
-                    we access this type either through TREE_TYPE field
-                    or via the tags list.  */
-                 TYPE_NAME (TREE_TYPE (x)) = x;
-                 pushtag (tname, TREE_TYPE (x), 0);
-               }
-           }
          my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140);
 
          if (type != error_mark_node
@@ -5823,6 +5809,12 @@ start_decl (declarator, declspecs, initialized)
          }
       }
 
+  /* Do this before the decl is actually defined so that the DWARF debug
+     info for the class reflects the declaration, rather than the
+     definition, of this decl.  */
+  if (TREE_CODE (decl) == VAR_DECL && context)
+    note_debug_info_needed (context);
+
   if (initialized)
     {
       if (! toplevel_bindings_p ()
@@ -6085,7 +6077,8 @@ grok_reference_init (decl, type, init, cleanupp)
     }
 
   tmp = convert_to_reference
-    (type, init, CONV_IMPLICIT, LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl);
+    (type, init, CONV_IMPLICIT,
+     LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND, decl);
 
   if (tmp == error_mark_node)
     goto fail;
@@ -6218,7 +6211,8 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
     {
       if (init && DECL_INITIAL (decl))
        DECL_INITIAL (decl) = init;
-      if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl))
+      if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl)
+         && DECL_VINDEX (decl))
        {
          tree stmt = DECL_VINDEX (decl);
          DECL_VINDEX (decl) = NULL_TREE;
@@ -6466,10 +6460,6 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
        /* Let debugger know it should output info for this type.  */
        note_debug_info_needed (ttype);
 
-      if (TREE_STATIC (decl) && DECL_CONTEXT (decl)
-         && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
-       note_debug_info_needed (DECL_CONTEXT (decl));
-
       if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
          && DECL_SIZE (decl) != NULL_TREE
          && ! TREE_CONSTANT (DECL_SIZE (decl)))
@@ -7813,7 +7803,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                    {
                      if (pedantic && ! in_system_header)
                        pedwarn ("ANSI C++ does not support `long long'");
-                     else if (longlong)
+                     if (longlong)
                        error ("`long long long' is too long for GCC");
                      else
                        longlong = 1;
@@ -7834,18 +7824,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          else
            {
              type = TREE_TYPE (id);
-             if (TREE_CODE (type) == TYPENAME_TYPE
-                 && TYPE_CONTEXT (type) == current_class_type)
-               {
-                 /* Members of the current class get resolved immediately;
-                    we couldn't catch this one earlier because we hadn't
-                    pushed into the class yet.  */
-                 if (TREE_TYPE (type))
-                   type = TREE_TYPE (type);
-                 else
-                   type = make_typename_type (TYPE_CONTEXT (type),
-                                              TYPE_IDENTIFIER (type));
-               }
              TREE_VALUE (spec) = type;
            }
          goto found;
@@ -8810,6 +8788,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              ;
            else if (TREE_COMPLEXITY (declarator) == current_class_depth)
              {
+               /* Resolve any TYPENAME_TYPEs from the decl-specifier-seq
+                  that refer to ctype.  They couldn't be resolved earlier
+                  because we hadn't pushed into the class yet.
+                  Example: resolve 'B<T>::type' in
+                  'B<typename B<T>::type> B<T>::f () { }'.  */
+               if (current_template_parms
+                   && uses_template_parms (type)
+                   && uses_template_parms (current_class_type))
+                 {
+                   tree args = current_template_args ();
+                   type = tsubst (type, &TREE_VEC_ELT (args, 0),
+                                  TREE_VEC_LENGTH (args), NULL_TREE);
+                 }
+
                /* This pop_nested_class corresponds to the
                    push_nested_class used to push into class scope for
                    parsing the argument list of a function decl, in
@@ -8831,19 +8823,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              }
            ctype = TREE_OPERAND (declarator, 0);
 
-           if (TREE_CODE (ctype) == TYPENAME_TYPE
-               && TYPE_CONTEXT (ctype) == current_class_type)
-             {
-               /* Members of the current class get resolved immediately;
-                  we couldn't catch this one earlier because we hadn't
-                  pushed into the class yet.  */
-               if (TREE_TYPE (ctype))
-                 ctype = TREE_TYPE (ctype);
-               else
-                 ctype = make_typename_type (TYPE_CONTEXT (ctype),
-                                             TYPE_IDENTIFIER (ctype));
-             }
-
            if (sname == NULL_TREE)
              goto done_scoping;
 
@@ -10139,7 +10118,7 @@ grok_op_properties (decl, virtualp, friendp)
          || name == ansi_opname[(int) METHOD_CALL_EXPR])
        return;                 /* no restrictions on args */
 
-      if (IDENTIFIER_TYPENAME_P (name))
+      if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
        {
          tree t = TREE_TYPE (name);
          if (TREE_CODE (t) == VOID_TYPE)
@@ -10153,7 +10132,9 @@ grok_op_properties (decl, virtualp, friendp)
 
              if (t == current_class_type)
                what = "the same type";
+             /* Don't force t to be complete here.  */
              else if (IS_AGGR_TYPE (t)
+                      && TYPE_SIZE (t)
                       && DERIVED_FROM_P (t, current_class_type))
                what = "a base class";
 
@@ -10735,7 +10716,8 @@ finish_enum (enumtype, values)
   }
 
   /* Finish debugging output for this type.  */
-  rest_of_type_compilation (enumtype, global_bindings_p ());
+  if (write_symbols != DWARF_DEBUG)
+    rest_of_type_compilation (enumtype, global_bindings_p ());
 
   return enumtype;
 }
@@ -11014,6 +10996,12 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
        }
     }
 
+  /* Do this before the decl is actually defined so that the DWARF debug
+     info for the class reflects the declaration, rather than the
+     definition, of this decl.  */
+  if (DECL_FUNCTION_MEMBER_P (decl1))
+    note_debug_info_needed (DECL_CLASS_CONTEXT (decl1));
+
   /* Warn if function was previously implicitly declared
      (but not if we warned then).  */
   if (! warn_implicit
@@ -12000,9 +11988,6 @@ finish_function (lineno, call_poplevel, nested)
          mark_inline_for_output (fndecl);
        }
 
-      if (ctype && TREE_ASM_WRITTEN (fndecl))
-       note_debug_info_needed (ctype);
-
       current_function_returns_null |= can_reach_end;
 
       /* Since we don't normally go through c_expand_return for constructors,
index 4bd06a3..5055d20 100644 (file)
@@ -42,7 +42,6 @@ extern tree cleanups_this_call;
 static void grok_function_init PROTO((tree, tree));
 void import_export_decl ();
 extern int current_class_depth;
-extern int symout_time;
 
 /* A list of virtual function tables we must make sure to write out.  */
 tree pending_vtables;
@@ -242,6 +241,10 @@ int warn_reorder;
 /* Non-zero means warn when synthesis behavior differs from Cfront's.  */
 int warn_synth;
 
+/* Non-zero means warn when we convert a pointer to member function
+   into a pointer to (void or function).  */
+int warn_pmf2ptr = 1;
+
 /* Nonzero means `$' can be in an identifier.
    See cccp.c for reasons why this breaks some obscure ANSI C programs.  */
 
@@ -555,6 +558,8 @@ lang_decode_option (p)
        warn_reorder = setting;
       else if (!strcmp (p, "synth"))
        warn_synth = setting;
+      else if (!strcmp (p, "pmf-conversions"))
+       warn_pmf2ptr = setting;
       else if (!strcmp (p, "comment"))
        ;                       /* cpp handles this one.  */
       else if (!strcmp (p, "comments"))
@@ -2642,9 +2647,6 @@ extern int parse_time, varconst_time;
 extern tree pending_templates;
 extern tree maybe_templates;
 
-#define TIMEVAR(VAR, BODY)    \
-do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
-
 extern struct obstack permanent_obstack;
 extern tree get_id_2 ();
 
@@ -2711,7 +2713,8 @@ finish_file ()
          instantiate_class_template (decl);
          if (CLASSTYPE_TEMPLATE_INSTANTIATION (decl))
            for (vars = TYPE_METHODS (decl); vars; vars = TREE_CHAIN (vars))
-             instantiate_decl (vars);
+             if (! DECL_ARTIFICIAL (vars))
+               instantiate_decl (vars);
        }
       else
        instantiate_decl (decl);
@@ -2768,13 +2771,6 @@ finish_file ()
     {
       tree decl = TREE_VALUE (vars);
 
-#ifdef DWARF_DEBUGGING_INFO
-       /* Output DWARF information for file-scope tentative data object
-          declarations.  */
-
-       if (write_symbols == DWARF_DEBUG)
-         TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
-#endif
       if (DECL_TEMPLATE_INSTANTIATION (decl)
          && ! DECL_IN_AGGR_P (decl))
        {
@@ -3430,6 +3426,9 @@ build_expr_from_tree (t)
     case TYPEID_EXPR:
       return build_x_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
 
+    case VAR_DECL:
+      return convert_from_reference (t);
+
     default:
       return t;
     }
index 80eb8e9..5adab9d 100644 (file)
@@ -1262,6 +1262,44 @@ dump_expr (t, nop)
       break;
 
     case CONSTRUCTOR:
+      if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
+       {
+         tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
+
+         if (integer_all_onesp (idx))
+           {
+             tree pfn = PFN_FROM_PTRMEMFUNC (t);
+             dump_expr (pfn);
+             break;
+           }
+         if (TREE_CODE (idx) == INTEGER_CST
+             && TREE_INT_CST_HIGH (idx) == 0)
+           {
+             tree virtuals;
+             unsigned HOST_WIDE_INT n;
+
+             t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
+             t = TYPE_METHOD_BASETYPE (t);
+             virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
+             
+             n = TREE_INT_CST_LOW (idx);
+
+             /* Map vtable index back one, to allow for the null pointer to
+                member.  */
+             --n;
+
+             while (n > 0 && virtuals)
+               {
+                 --n;
+                 virtuals = TREE_CHAIN (virtuals);
+               }
+             if (virtuals)
+               {
+                 dump_expr (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)));
+                 break;
+               }
+           }
+       }
       OB_PUTC ('{');
       dump_expr_list (CONSTRUCTOR_ELTS (t));
       OB_PUTC ('}');
index 54c214e..1869aef 100644 (file)
@@ -101,3 +101,5 @@ Boston, MA 02111-1307, USA.  */
   "-Wno-reorder",
   "-Wsynth",
   "-Wno-synth",
+  "-Wpmf-conversions",
+  "-Wno-pmf-conversions",
index f032c9b..c7e3a87 100644 (file)
@@ -2116,7 +2116,9 @@ synthesize_method (fndecl)
   tree context = hack_decl_function_context (fndecl);
   tree base = DECL_CLASS_CONTEXT (fndecl);
 
-  if (nested)
+  if (! context)
+    push_to_top_level ();
+  else if (nested)
     push_cp_function_context (context);
 
   interface_unknown = 1;
@@ -2156,6 +2158,8 @@ synthesize_method (fndecl)
     }
 
   extract_interface_info ();
-  if (nested)
+  if (! context)
+    pop_from_top_level ();
+  else if (nested)
     pop_cp_function_context (context);
 }
index d29d4a8..cb80c8e 100644 (file)
@@ -2233,7 +2233,10 @@ named_complex_class_head_sans_basetype:
                {
                  current_aggr = $1;
                  if (TREE_CODE ($3) == TYPE_DECL)
-                   $$ = $3;
+                   {
+                     $$ = $3;
+                     note_debug_info_needed (DECL_CONTEXT ($$));
+                   }
                  else
                    {
                      cp_error ("`%T' does not have a nested type named `%D'",
index f5f502d..46a8a14 100644 (file)
@@ -198,26 +198,13 @@ end_template_decl ()
   (void) get_pending_sizes (); /* Why? */
 }
 
-void
-push_template_decl (decl)
-     tree decl;
+/* Generate a valid set of template args from current_template_parms.  */
+
+tree
+current_template_args ()
 {
   tree header = current_template_parms;
-  tree tmpl;
   tree args = NULL_TREE;
-  tree info;
-  tree ctx = DECL_CONTEXT (decl) ? DECL_CONTEXT (decl) : current_class_type;
-  int primary = 0;
-
-  /* Kludge! */
-  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)
-      && DECL_CLASS_CONTEXT (decl))
-    ;
-  /* Note that this template is a "primary template" */
-  else if (! ctx || ! CLASSTYPE_TEMPLATE_INFO (ctx)
-      /* || (processing_template_decl > CLASSTYPE_TEMPLATE_LEVEL (ctx)) */)
-    primary = 1;
-
   while (header)
     {
       tree a = copy_node (TREE_VALUE (header));
@@ -236,8 +223,32 @@ push_template_decl (decl)
       header = TREE_CHAIN (header);
     }
   args = nreverse (args);
+
+  /* FIXME Remove this when we support member templates.  */
   args = TREE_VALUE (args);
 
+  return args;
+}
+  
+void
+push_template_decl (decl)
+     tree decl;
+{
+  tree tmpl;
+  tree args = NULL_TREE;
+  tree info;
+  tree ctx = DECL_CONTEXT (decl) ? DECL_CONTEXT (decl) : current_class_type;
+  int primary = 0;
+
+  /* Kludge! */
+  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)
+      && DECL_CLASS_CONTEXT (decl))
+    ;
+  /* Note that this template is a "primary template" */
+  else if (! ctx || ! CLASSTYPE_TEMPLATE_INFO (ctx)
+      /* || (processing_template_decl > CLASSTYPE_TEMPLATE_LEVEL (ctx)) */)
+    primary = 1;
+
   /* Partial specialization.  */
   if (TREE_CODE (decl) == TYPE_DECL
       && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
@@ -262,6 +273,8 @@ push_template_decl (decl)
       return;
     }
 
+  args = current_template_args ();
+
   if (! ctx || TYPE_BEING_DEFINED (ctx))
     {
       tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);
index f51ea64..1ecccd8 100644 (file)
@@ -175,6 +175,12 @@ get_tinfo_fn_dynamic (exp)
   if (exp == error_mark_node)
     return error_mark_node;
 
+  if (type_unknown_p (exp))
+    {
+      error ("typeid of overloaded function");
+      return error_mark_node;
+    }
+
   type = TREE_TYPE (exp);
 
   /* peel back references, so they match.  */
@@ -244,6 +250,10 @@ build_x_typeid (exp)
     }
 
   exp = get_tinfo_fn_dynamic (exp);
+
+  if (exp == error_mark_node)
+    return error_mark_node;
+
   exp = build_call (exp, type, NULL_TREE);
 
   if (cond)
@@ -316,9 +326,17 @@ tree
 get_tinfo_fn (type)
      tree type;
 {
-  tree name = build_overload_with_type (tinfo_fn_id, type);
+  tree name;
   tree d;
 
+  if (TREE_CODE (type) == OFFSET_TYPE)
+    type = TREE_TYPE (type);
+  if (TREE_CODE (type) == METHOD_TYPE)
+    type = build_function_type (TREE_TYPE (type),
+                               TREE_CHAIN (TYPE_ARG_TYPES (type)));
+
+  name = build_overload_with_type (tinfo_fn_id, type);
+
   if (IDENTIFIER_GLOBAL_VALUE (name))
     return IDENTIFIER_GLOBAL_VALUE (name);
 
@@ -330,7 +348,7 @@ get_tinfo_fn (type)
   DECL_ARTIFICIAL (d) = 1;
   DECL_NOT_REALLY_EXTERN (d) = 1;
   DECL_MUTABLE_P (d) = 1;
-  TREE_TYPE (name) = type;
+  TREE_TYPE (name) = copy_to_permanent (type);
   pushdecl_top_level (d);
   make_function_rtl (d);
   assemble_external (d);
index ebb692d..f2b2a50 100644 (file)
@@ -2539,9 +2539,20 @@ dfs_debug_mark (binfo)
 
   CLASSTYPE_DEBUG_REQUESTED (t) = 1;
 
-  /* If interface info is known, the value of (?@@?) is correct.  */
-  if (methods == 0
-      || CLASSTYPE_INTERFACE_KNOWN (t)
+  if (methods == 0)
+    return;
+
+  /* We can't do the TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which
+     does not support name references between translation units.  */
+  if (write_symbols == DWARF_DEBUG)
+    {
+      rest_of_type_compilation (t, global_bindings_p ());
+      return;
+    }
+
+  /* If interface info is known, either we've already emitted the debug
+     info or we don't need to.  */
+  if (CLASSTYPE_INTERFACE_KNOWN (t)
       || (write_virtuals == 2 && TYPE_VIRTUAL_P (t)))
     return;
 
@@ -3120,6 +3131,10 @@ note_debug_info_needed (type)
      tree type;
 {
   tree field;
+
+  if (current_template_parms)
+    return;
+
   dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
     {
index 0d0dc05..c391d7a 100644 (file)
@@ -1592,6 +1592,16 @@ mapcar (t, func)
       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
       TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
       return t;
+      break;
+
+    case RTL_EXPR:
+      t = copy_node (t);
+      if (RTL_EXPR_SEQUENCE (t))
+       RTL_EXPR_SEQUENCE (t) = copy_rtx (RTL_EXPR_SEQUENCE (t));
+      if (RTL_EXPR_RTL (t))
+       RTL_EXPR_RTL (t) = copy_rtx (RTL_EXPR_RTL (t));
+      return t;
+      break;
 
     case CONVERT_EXPR:
     case ADDR_EXPR:
index 4c876f6..60c8f00 100644 (file)
@@ -2822,9 +2822,9 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
            }
          else
            {
-             parmval = convert_for_initialization (return_loc, type, val,
-                                                   flags|INDIRECT_BIND,
-                                                   "argument passing", fndecl, i);
+             parmval = convert_for_initialization
+               (return_loc, type, val, flags,
+                "argument passing", fndecl, i);
 #ifdef PROMOTE_PROTOTYPES
              if ((TREE_CODE (type) == INTEGER_TYPE
                   || TREE_CODE (type) == ENUMERAL_TYPE)
@@ -4616,7 +4616,8 @@ mark_addressable (exp)
       case PARM_DECL:
        if (x == current_class_ptr)
          {
-           error ("address of `this' not available");
+           if (! flag_this_is_variable)
+             error ("address of `this' not available");
            TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later */
            put_var_into_stack (x);
            return 1;
@@ -4649,8 +4650,10 @@ mark_addressable (exp)
 
       case CONST_DECL:
       case RESULT_DECL:
-       /* For C++, we don't warn about taking the address of a register
-          variable for CONST_DECLs; ARM p97 explicitly says it's okay.  */
+       if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
+           && !DECL_ARTIFICIAL (x) && extra_warnings)
+         cp_warning ("address requested for `%D', which is declared `register'",
+                     x);
        put_var_into_stack (x);
        TREE_ADDRESSABLE (x) = 1;
        return 1;
@@ -4678,6 +4681,11 @@ mark_addressable (exp)
        TREE_ADDRESSABLE (x) = 1;
        return 1;
 
+      case TARGET_EXPR:
+       TREE_ADDRESSABLE (x) = 1;
+       mark_addressable (TREE_OPERAND (x, 0));
+       return 1;
+
       default:
        return 1;
     }
@@ -6082,7 +6090,7 @@ get_delta_difference (from, to, force)
   binfo = get_binfo (from, to, 1);
   if (binfo == error_mark_node)
     {
-      error ("   in pointer to member function conversion");
+      error ("   in pointer to member function conversiona");
       return delta;
     }
   if (binfo == 0)
@@ -6096,12 +6104,14 @@ get_delta_difference (from, to, force)
       binfo = get_binfo (to, from, 1);
       if (binfo == error_mark_node)
        {
-         error ("   in pointer to member conversion");
+         if (!force)
+           error ("   in pointer to member conversion");
          return delta;
        }
       if (binfo == 0)
        {
-         cp_error ("cannot convert pointer to member of type %T to unrelated pointer to member of type %T", from, to);
+         if (!force)
+           cp_error ("cannot convert pointer to member of type %T to unrelated pointer to member of type %T", from, to);
          return delta;
        }
       if (TREE_VIA_VIRTUAL (binfo))
@@ -6751,6 +6761,13 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
     }
   else if (TYPE_HAS_CONSTRUCTOR (type) || IS_AGGR_TYPE (TREE_TYPE (rhs)))
     return convert (type, rhs);
+  /* Handle anachronistic conversions from (::*)() to void* or (*)().  */
+  else if (TREE_CODE (type) == POINTER_TYPE
+          && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
+              || TREE_TYPE (type) == void_type_node)
+          && TREE_TYPE (rhs)
+          && TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
+    return convert (type, rhs);
 
   cp_error ("%s to `%T' from `%T'", errtype, type, rhstype);
   return error_mark_node;
@@ -7180,7 +7197,7 @@ c_expand_return (retval)
   if (retval == result
       || DECL_CONSTRUCTOR_P (current_function_decl))
     /* It's already done for us.  */;
-  else if (TYPE_MODE (TREE_TYPE (retval)) == VOIDmode)
+  else if (TREE_TYPE (retval) == void_type_node)
     {
       pedwarn ("return of void value in function returning non-void");
       expand_expr_stmt (retval);
index 9395cc8..1c00297 100644 (file)
@@ -829,7 +829,9 @@ digest_init (type, init, tail)
            }
          init = element;
        }
-      while (TREE_CODE (init) == CONSTRUCTOR)
+      while (TREE_CODE (init) == CONSTRUCTOR
+            && ! (TREE_TYPE (init)
+                  && TYPE_PTRMEMFUNC_P (TREE_TYPE (init))))
        {
          cp_pedwarn ("braces around scalar initializer for `%T'", type);
          init = CONSTRUCTOR_ELTS (init);