method.c (set_mangled_name_for_decl): Change return type to void.
authorJason Merrill <jason@yorick.cygnus.com>
Mon, 3 Aug 1998 22:11:25 +0000 (22:11 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 3 Aug 1998 22:11:25 +0000 (18:11 -0400)
* method.c (set_mangled_name_for_decl): Change return type to void.
* decl.c (lookup_name_real): A namespace-level decl takes priority
over implicit typename.  Avoid doing the same lookup twice.
* search.c (dependent_base_p): New fn.
(dfs_pushdecls, dfs_compress_decls): Use it.
* typeck.c (get_member_function_from_ptrfunc): Don't try to handle
virtual functions if the type doesn't have any.

From-SVN: r21551

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/method.c
gcc/cp/search.c
gcc/cp/typeck.c

index ee6b01f..2d2e7dc 100644 (file)
@@ -1,3 +1,16 @@
+1998-08-03  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * method.c (set_mangled_name_for_decl): Change return type to void.
+
+       * decl.c (lookup_name_real): A namespace-level decl takes priority
+       over implicit typename.  Avoid doing the same lookup twice.
+
+       * search.c (dependent_base_p): New fn.
+       (dfs_pushdecls, dfs_compress_decls): Use it.
+
+       * typeck.c (get_member_function_from_ptrfunc): Don't try to handle 
+       virtual functions if the type doesn't have any.
+
 1998-08-03  Mark Mitchell  <mark@markmitchell.com>
 
        * decl2.c (grokfield): Don't mangle the name of a TYPE_DECL if it
index 72a1655..aa84e0f 100644 (file)
@@ -2733,7 +2733,7 @@ extern tree build_static_name                     PROTO((tree, tree));
 extern tree build_decl_overload                        PROTO((tree, tree, int));
 extern tree build_decl_overload_real            PROTO((tree, tree, tree, tree,
                                                       tree, int)); 
-extern tree set_mangled_name_for_decl           PROTO((tree));
+extern void set_mangled_name_for_decl           PROTO((tree));
 extern tree build_typename_overload            PROTO((tree));
 extern tree build_overload_with_type           PROTO((tree, tree));
 extern tree build_destructor_name              PROTO((tree));
index 0b32a3d..6841905 100644 (file)
@@ -5074,11 +5074,11 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
       /* Add implicit 'typename' to types from template bases.  lookup_field
          will do this for us.  If classval is actually from an enclosing
          scope, lookup_nested_field will get it for us.  */
-      if (processing_template_decl
-         && classval && TREE_CODE (classval) == TYPE_DECL
-         && ! currently_open_class (DECL_CONTEXT (classval))
-         && uses_template_parms (current_class_type)
-         && ! DECL_ARTIFICIAL (classval))
+      else if (processing_template_decl
+              && classval && TREE_CODE (classval) == TYPE_DECL
+              && ! currently_open_class (DECL_CONTEXT (classval))
+              && uses_template_parms (current_class_type)
+              && ! DECL_ARTIFICIAL (classval))
        classval = lookup_field (current_class_type, name, 0, 1);
 
       /* yylex() calls this with -2, since we should never start digging for
@@ -5121,6 +5121,28 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
   else
     val = unqualified_namespace_lookup (name, flags);
 
+  if (classval && TREE_CODE (val) == TYPE_DECL
+      && TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE
+      && TREE_TYPE (TREE_TYPE (val)))
+    {
+      tree nsval = unqualified_namespace_lookup (name, flags);
+
+      if (val && nsval && TREE_CODE (nsval) == TYPE_DECL)
+       {
+         static int explained;
+         cp_warning ("namespace-scope type `%#D'", nsval);
+         cp_warning
+           ("  is used instead of `%D' from dependent base class", val);
+         if (! explained)
+           {
+             explained = 1;
+             cp_warning ("  (use `typename %D' if that's what you meant)",
+                         val);
+           }
+         val = nsval;
+       }
+    }
+
  done:
   if (val)
     {
index 18e638c..69ba1b0 100644 (file)
@@ -1663,7 +1663,7 @@ build_decl_overload (dname, parms, for_method)
 
 /* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL.  */
 
-tree
+void
 set_mangled_name_for_decl (decl)
      tree decl;
 {
index bde0a29..79042e1 100644 (file)
@@ -3480,6 +3480,23 @@ envelope_add_decl (type, decl, values)
     }
 }
 
+/* Returns 1 iff BINFO is a base we shouldn't really be able to see into,
+   because it (or one of the intermediate bases) depends on template parms.  */
+
+static int
+dependent_base_p (binfo)
+     tree binfo;
+{
+  for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
+    {
+      if (binfo == current_class_type)
+       break;
+      if (uses_template_parms (TREE_TYPE (binfo)))
+       return 1;
+    }
+  return 0;
+}
+
 /* Add the instance variables which this class contributed to the
    current class binding contour.  When a redefinition occurs, if the
    redefinition is strictly within a single inheritance path, we just
@@ -3506,9 +3523,18 @@ dfs_pushdecls (binfo)
   tree type = BINFO_TYPE (binfo);
   tree fields, *methods, *end;
   tree method_vec;
+  int dummy = 0;
+
+  /* Only record types if we're a template base.  */
+  if (processing_template_decl && type != current_class_type
+      && dependent_base_p (binfo))
+    dummy = 1;
 
   for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
     {
+      if (dummy && TREE_CODE (fields) != TYPE_DECL)
+       continue;
+
       /* Unmark so that if we are in a constructor, and then find that
         this field was initialized by a base initializer,
         we can emit an error message.  */
@@ -3546,7 +3572,7 @@ dfs_pushdecls (binfo)
     }
 
   method_vec = CLASSTYPE_METHOD_VEC (type);
-  if (method_vec)
+  if (method_vec && ! dummy)
     {
       /* Farm out constructors and destructors.  */
       methods = &TREE_VEC_ELT (method_vec, 2);
@@ -3598,7 +3624,10 @@ dfs_compress_decls (binfo)
   tree type = BINFO_TYPE (binfo);
   tree method_vec = CLASSTYPE_METHOD_VEC (type);
 
-  if (method_vec != 0)
+  if (processing_template_decl && type != current_class_type
+      && dependent_base_p (binfo))
+    /* We only record types if we're a template base.  */;
+  else if (method_vec != 0)
     {
       /* Farm out constructors and destructors.  */
       tree *methods = &TREE_VEC_ELT (method_vec, 2);
index 0ae703b..3e4fd0a 100644 (file)
@@ -2669,7 +2669,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
     {
       tree fntype, idx, e1, delta, delta2, e2, e3, aref, vtbl;
-      tree instance;
+      tree instance, basetype;
 
       tree instance_ptr = *instance_ptrptr;
 
@@ -2680,61 +2680,76 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
        function = save_expr (function);
 
       fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
+      basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
 
-      /* Promoting idx before saving it improves performance on RISC
-        targets.  Without promoting, the first compare used
-        load-with-sign-extend, while the second used normal load then
-        shift to sign-extend.  An optimizer flaw, perhaps, but it's easier
-        to make this change.  */
-      idx = save_expr (default_conversion
-                      (build_component_ref (function,
-                                            index_identifier,
-                                            NULL_TREE, 0)));
-      e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1);
       delta = cp_convert (ptrdiff_type_node,
                          build_component_ref (function, delta_identifier,
                                               NULL_TREE, 0));
-      delta2 = DELTA2_FROM_PTRMEMFUNC (function);
-
-      /* Convert down to the right base, before using the instance.  */
-      instance
-       = convert_pointer_to_real (TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)),
-                                  instance_ptr);
-      if (instance == error_mark_node && instance_ptr != error_mark_node)
-       return instance;
-
-      vtbl = convert_pointer_to (ptr_type_node, instance);
-      vtbl
-       = build (PLUS_EXPR,
-                build_pointer_type (build_pointer_type (vtable_entry_type)),
-                vtbl, cp_convert (ptrdiff_type_node, delta2));
-      vtbl = build_indirect_ref (vtbl, NULL_PTR);
-      aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR,
-                                                    idx,
-                                                    integer_one_node, 1));
-      if (! flag_vtable_thunks)
-       {
-         aref = save_expr (aref);
-
-         delta = build_binary_op
+      e3 = PFN_FROM_PTRMEMFUNC (function);
+
+      if (TYPE_SIZE (basetype) != NULL_TREE
+         && ! TYPE_VIRTUAL_P (basetype))
+       /* If basetype doesn't have virtual functions, don't emit code to
+          handle that case.  */
+       e1 = e3;
+      else
+       {
+         /* Promoting idx before saving it improves performance on RISC
+            targets.  Without promoting, the first compare used
+            load-with-sign-extend, while the second used normal load then
+            shift to sign-extend.  An optimizer flaw, perhaps, but it's
+            easier to make this change.  */
+         idx = save_expr (default_conversion
+                          (build_component_ref (function,
+                                                index_identifier,
+                                                NULL_TREE, 0)));
+         e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1);
+
+         /* Convert down to the right base, before using the instance.  */
+         instance = convert_pointer_to_real (basetype, instance_ptr);
+         if (instance == error_mark_node && instance_ptr != error_mark_node)
+           return instance;
+
+         vtbl = convert_pointer_to (ptr_type_node, instance);
+         delta2 = DELTA2_FROM_PTRMEMFUNC (function);
+         vtbl = build
            (PLUS_EXPR,
-            build_conditional_expr (e1, build_component_ref (aref,
+            build_pointer_type (build_pointer_type (vtable_entry_type)),
+            vtbl, cp_convert (ptrdiff_type_node, delta2));
+         vtbl = build_indirect_ref (vtbl, NULL_PTR);
+         aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR,
+                                                        idx,
+                                                        integer_one_node, 1));
+         if (! flag_vtable_thunks)
+           {
+             aref = save_expr (aref);
+
+             delta = build_binary_op
+               (PLUS_EXPR,
+                build_conditional_expr (e1,
+                                        build_component_ref (aref,
                                                              delta_identifier,
                                                              NULL_TREE, 0),
-                                    integer_zero_node),
-            delta, 1);
+                                        integer_zero_node),
+                delta, 1);
+           }
+
+         if (flag_vtable_thunks)
+           e2 = aref;
+         else
+           e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
+         TREE_TYPE (e2) = TREE_TYPE (e3);
+         e1 = build_conditional_expr (e1, e2, e3);
+
+         /* Make sure this doesn't get evaluated first inside one of the
+            branches of the COND_EXPR.  */
+         if (TREE_CODE (instance_ptr) == SAVE_EXPR)
+           e1 = build (COMPOUND_EXPR, TREE_TYPE (e1),
+                       instance_ptr, e1);
        }
 
       *instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr),
                                instance_ptr, delta);
-      if (flag_vtable_thunks)
-       e2 = aref;
-      else
-       e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
-
-      e3 = PFN_FROM_PTRMEMFUNC (function);
-      TREE_TYPE (e2) = TREE_TYPE (e3);
-      e1 = build_conditional_expr (e1, e2, e3);
 
       if (instance_ptr == error_mark_node
          && TREE_CODE (e1) != ADDR_EXPR
@@ -2742,12 +2757,6 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
        cp_error ("object missing in `%E'", function);
 
       function = e1;
-
-      /* Make sure this doesn't get evaluated first inside one of the
-         branches of the COND_EXPR.  */
-      if (TREE_CODE (instance_ptr) == SAVE_EXPR)
-       function = build (COMPOUND_EXPR, TREE_TYPE (function),
-                         instance_ptr, function);
     }
   return function;
 }