OSDN Git Service

* typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 May 1999 15:42:55 +0000 (15:42 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 May 1999 15:42:55 +0000 (15:42 +0000)
reveal optimization opportunities.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@27084 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/typeck.c

index 5337856..6ff46de 100644 (file)
@@ -1,5 +1,8 @@
 1999-05-21  Mark Mitchell  <mark@codesourcery.com>
 
+       * typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to
+       reveal optimization opportunities.
+
        * pt.c (tsubst): Don't issue error messages when we're not
        complaining, even if we see a qualified function type.
        (check_cv_quals_for_unify): Don't allow a qualified function
index c8c11ca..17147b9 100644 (file)
@@ -6515,15 +6515,15 @@ build_ptrmemfunc (type, pfn, force)
      tree type, pfn;
      int force;
 {
-  tree idx = integer_zero_node;
-  tree delta = integer_zero_node;
-  tree delta2 = integer_zero_node;
-  tree npfn = NULL_TREE;
   tree fn;
   
   /* Handle multiple conversions of pointer to member functions.  */
   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
     {
+      tree idx = integer_zero_node;
+      tree delta = integer_zero_node;
+      tree delta2 = integer_zero_node;
+      tree npfn = NULL_TREE;
       tree ndelta, ndelta2;
       tree e1, e2, e3, n;
       tree pfn_type;
@@ -6537,18 +6537,42 @@ build_ptrmemfunc (type, pfn, force)
          && comp_target_types (type, pfn_type, 1) != 1)
        cp_error ("conversion to `%T' from `%T'", type, pfn_type);
 
-      ndelta = cp_convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0));
-      ndelta2 = cp_convert (ptrdiff_type_node, DELTA2_FROM_PTRMEMFUNC (pfn));
-      idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
+      if (TREE_CODE (pfn) == PTRMEM_CST)
+       {
+         /* We could just build the resulting CONSTRUCTOR now, but we
+            don't, relying on the general machinery below, together
+            with constant-folding, to do the right thing.  We don't
+            want to return a PTRMEM_CST here, even though we could,
+            because a pointer-to-member constant ceases to be a
+            constant (from the point of view of the language) when it
+            is cast to another type.  */
+
+         expand_ptrmemfunc_cst (pfn, &ndelta, &idx, &npfn, &ndelta2);
+         if (npfn)
+           /* This constant points to a non-virtual function.
+              NDELTA2 will be NULL, but it's value doesn't really
+              matter since we won't use it anyhow.  */
+           ndelta2 = integer_zero_node;
+       }
+      else
+       {
+         ndelta = cp_convert (ptrdiff_type_node, 
+                              build_component_ref (pfn, 
+                                                   delta_identifier, 
+                                                   NULL_TREE, 0));
+         ndelta2 = cp_convert (ptrdiff_type_node, 
+                               DELTA2_FROM_PTRMEMFUNC (pfn));
+         idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
+       }
 
       n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (pfn_type)),
                                TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
                                force);
-
       delta = build_binary_op (PLUS_EXPR, ndelta, n);
       delta2 = build_binary_op (PLUS_EXPR, ndelta2, n);
       e1 = fold (build (GT_EXPR, boolean_type_node, idx, integer_zero_node));
          
+      /* If it's a virtual function, this is what we want.  */
       e2 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx,
                              NULL_TREE, delta2);
 
@@ -6556,8 +6580,10 @@ build_ptrmemfunc (type, pfn, force)
       npfn = build1 (NOP_EXPR, type, pfn);
       TREE_CONSTANT (npfn) = TREE_CONSTANT (pfn);
 
-      e3 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx, npfn,
-                             NULL_TREE);
+      /* But if it's a non-virtual function, or NULL, we use this
+        instead.  */
+      e3 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta,
+                             idx, npfn, NULL_TREE);
       return build_conditional_expr (e1, e2, e3);
     }