OSDN Git Service

* class.c (instantiate_type): Don't treat template-ids that don't
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Jun 1998 09:47:04 +0000 (09:47 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Jun 1998 09:47:04 +0000 (09:47 +0000)
specify any template arguments as equivalent to ordinary
identifiers.  Use OFFSET_REF instead of SCOPE_REF to refer to
pointer-to-members for member templates.  Tidy slightly.
* cp-tree.def (TEMPLATE_ID_EXPR): Revise documentation.
* init.c (build_offset_ref): Handle template-ids like ordinary
identifiers, for the most part, but store a TEMPLATE_ID_EXPR in the
offset part of the OFFSET_REF.
* typeck.c (build_unary_op): Change check for unknown types to
look for OFFSET_REFs, not SCOPE_REFs.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.def
gcc/cp/init.c
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C

index 5539b4c..aced365 100644 (file)
@@ -1,3 +1,16 @@
+1998-06-12  Mark Mitchell  <mark@markmitchell.com>
+
+       * class.c (instantiate_type): Don't treat template-ids that don't
+       specify any template arguments as equivalent to ordinary
+       identifiers.  Use OFFSET_REF instead of SCOPE_REF to refer to
+       pointer-to-members for member templates.  Tidy slightly.
+       * cp-tree.def (TEMPLATE_ID_EXPR): Revise documentation.
+       * init.c (build_offset_ref): Handle template-ids like ordinary
+       identifiers, for the most part, but store a TEMPLATE_ID_EXPR in the
+       offset part of the OFFSET_REF.
+       * typeck.c (build_unary_op): Change check for unknown types to
+       look for OFFSET_REFs, not SCOPE_REFs.
+
 1998-06-11  Mark Mitchell  <mark@markmitchell.com>
 
        * pt.c (is_member_template_class): New function.
index 0e1aa26..6e3942f 100644 (file)
@@ -4961,6 +4961,7 @@ instantiate_type (lhstype, rhs, complain)
      int complain;
 {
   tree explicit_targs = NULL_TREE;
+  int template_only = 0;
 
   if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
     {
@@ -5090,38 +5091,28 @@ instantiate_type (lhstype, rhs, complain)
        return rhs;
       }
 
-    case SCOPE_REF:
-      {
-       /* This can happen if we are forming a pointer-to-member for a
-          member template.  */
-       tree template_id_expr = TREE_OPERAND (rhs, 1);
-       tree name;
-       my_friendly_assert (TREE_CODE (template_id_expr) == TEMPLATE_ID_EXPR,
-                           0);
-       explicit_targs = TREE_OPERAND (template_id_expr, 1);
-       name = TREE_OPERAND (template_id_expr, 0);
-       my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
-       rhs = lookup_fnfields (TYPE_BINFO (TREE_OPERAND (rhs, 0)), name, 1);
-       goto overload;
-      }
+    case OFFSET_REF:
+      /* This can happen if we are forming a pointer-to-member for a
+        member template.  */
+      rhs = TREE_OPERAND (rhs, 1);
+      my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0);
+       
+      /* Fall through.  */
 
     case TEMPLATE_ID_EXPR:
       {
        explicit_targs = TREE_OPERAND (rhs, 1);
+       template_only = 1;
        rhs = TREE_OPERAND (rhs, 0);
       }
       /* fall through */
       my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);
 
     case OVERLOAD:
-    overload:
       {
        tree elem, elems;
 
-       /* First look for an exact match.  Search overloaded
-          functions.  May have to undo what `default_conversion'
-          might do to lhstype.  */
-
+       /* Check that the LHSTYPE and the RHS are reasonable.  */
        lhstype = validate_lhs (lhstype, complain);
        if (lhstype == error_mark_node)
          return lhstype;
@@ -5129,30 +5120,32 @@ instantiate_type (lhstype, rhs, complain)
        if (TREE_CODE (lhstype) != FUNCTION_TYPE
            && TREE_CODE (lhstype) != METHOD_TYPE)
          {
-           rhs = DECL_NAME (OVL_FUNCTION (rhs));
            if (complain)
              cp_error("cannot resolve overloaded function `%D' " 
-                      "based on non-function type", rhs);
+                      "based on non-function type", 
+                      DECL_NAME (OVL_FUNCTION (rhs)));
            return error_mark_node;
          }
        
-       elems = rhs;
-       /* If there are explicit_targs, only a template function
-          can match.  */
-       if (explicit_targs == NULL_TREE)
-         while (elems)
-           {
-             elem = OVL_FUNCTION (elems);
-             if (! comptypes (lhstype, TREE_TYPE (elem), 1))
-               elems = OVL_CHAIN (elems);
-             else
-               {
-                 mark_used (elem);
-                 return elem;
-               }
-           }
+       /* Look for an exact match, by searching through the
+          overloaded functions.  */
+       if (template_only)
+         /* If we're processing a template-id, only a template
+            function can match, so we don't look through the
+            overloaded functions.  */
+         ;
+       else for (elems = rhs; elems; elems = OVL_CHAIN (elems))
+         {
+           elem = OVL_FUNCTION (elems);
+           if (comptypes (lhstype, TREE_TYPE (elem), 1))
+             {
+               mark_used (elem);
+               return elem;
+             }
+         }
 
-       /* No exact match found, look for a compatible template.  */
+       /* No overloaded function was an exact match.  See if we can
+          instantiate some template to match.  */
        {
          tree save_elem = 0;
          elems = rhs;
@@ -5189,14 +5182,14 @@ instantiate_type (lhstype, rhs, complain)
            }
        }
 
-       /* If there are explicit_targs, only a template function
-          can match.  */
-       if (explicit_targs == NULL_TREE) 
+       /* There's no exact match, and no templates can be
+          instantiated to match.  The last thing we try is to see if
+          some ordinary overloaded function is close enough.  If
+          we're only looking for template functions, we don't do
+          this.  */
+       if (!template_only)
          {
-           /* No match found, look for a compatible function.  */
-           tree elems = rhs;
-           elems = rhs;
-           for (; elems; elems = OVL_NEXT (elems))
+           for (elems = rhs; elems; elems = OVL_NEXT (elems))
              {
                elem = OVL_CURRENT (elems);
                if (comp_target_types (lhstype, TREE_TYPE (elem), 1) > 0)
@@ -5228,6 +5221,8 @@ instantiate_type (lhstype, rhs, complain)
                return save_elem;
              }
          }
+
+       /* We failed to find a match.  */
        if (complain)
          {
            cp_error ("cannot resolve overload to target type `%#T'", lhstype);
index cad0a59..dbbdb66 100644 (file)
@@ -163,7 +163,7 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2)
    template will be a FUNCTION_DECL, TEMPLATE_DECL, or a list of
    overloaded functions and templates if the template-id refers to
    a global template.  If the template-id refers to a member template,
-   the template will be an IDENTIFIER_NODE.  */
+   the template may be an IDENTIFIER_NODE.  */
 DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
 
 /* An association between namespace and entity. Parameters are the
index 59491a7..cf6378b 100644 (file)
@@ -1522,6 +1522,7 @@ build_offset_ref (type, name)
   tree decl, fnfields, fields, t = error_mark_node;
   tree basebinfo = NULL_TREE;
   int dtor = 0;
+  tree orig_name = name;
 
   /* class templates can come in as TEMPLATE_DECLs here.  */
   if (TREE_CODE (name) == TEMPLATE_DECL)
@@ -1532,8 +1533,6 @@ build_offset_ref (type, name)
 
   if (processing_template_decl || uses_template_parms (type))
     return build_min_nt (SCOPE_REF, type, name);
-  else if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
-    return build (SCOPE_REF, unknown_type_node, type, name);
 
   /* Handle namespace names fully here.  */
   if (TREE_CODE (type) == NAMESPACE_DECL)
@@ -1542,6 +1541,16 @@ build_offset_ref (type, name)
   if (type == NULL_TREE || ! is_aggr_type (type, 1))
     return error_mark_node;
 
+  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+    {
+      /* If the NAME is a TEMPLATE_ID_EXPR, we are looking at
+        something like `a.template f<int>' or the like.  For the most
+        part, we treat this just like a.f.  We do remember, however,
+        the template-id that was used.  */
+      name = TREE_OPERAND (orig_name, 0);
+      my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
+    }
+
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
       dtor = 1;
@@ -1612,11 +1621,33 @@ build_offset_ref (type, name)
   if (fnfields)
     {
       extern int flag_save_memoized_contexts;
-      basebinfo = TREE_PURPOSE (fnfields);
 
       /* Go from the TREE_BASELINK to the member function info.  */
       t = TREE_VALUE (fnfields);
 
+      if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
+       {
+         /* The FNFIELDS are going to contain functions that aren't
+            necessarily templates, and templates that don't
+            necessarily match the explicit template parameters.  We
+            save all the functions, and the explicit parameters, and
+            then figure out exactly what to instantiate with what
+            arguments in instantiate_type.  */
+
+         if (TREE_CODE (t) != OVERLOAD)
+           /* The code in instantiate_type which will process this
+              expects to encounter OVERLOADs, not raw functions.  */
+           t = ovl_cons (t, NULL_TREE);
+         
+         return build (OFFSET_REF, 
+                       build_offset_type (type, unknown_type_node),
+                       decl,
+                       build (TEMPLATE_ID_EXPR, 
+                              TREE_TYPE (t),
+                              t,
+                              TREE_OPERAND (orig_name, 1)));
+       }
+
       if (!really_overloaded_fn (t))
        {
          tree access;
@@ -1625,6 +1656,7 @@ build_offset_ref (type, name)
          t = OVL_CURRENT (t);
 
          /* unique functions are handled easily.  */
+         basebinfo = TREE_PURPOSE (fnfields);
          access = compute_access (basebinfo, t);
          if (access == access_protected_node)
            {
index d417afb..4b2e587 100644 (file)
@@ -4527,7 +4527,7 @@ build_unary_op (code, xarg, noconvert)
        }
 
       if (TREE_CODE (arg) == OVERLOAD 
-         || (TREE_CODE (arg) == SCOPE_REF 
+         || (TREE_CODE (arg) == OFFSET_REF
              && TREE_CODE (TREE_OPERAND (arg, 1)) == TEMPLATE_ID_EXPR))
        return build1 (ADDR_EXPR, unknown_type_node, arg);
       else if (TREE_CODE (arg) == TREE_LIST)
index 3cd9c2b..e14c726 100644 (file)
@@ -1,10 +1,8 @@
-// Build don't run:
-
 class foo
 {
 public:
   template<class T>
-  T bar() {}
+  T bar() { return 7; }
 };
 
 int
@@ -13,4 +11,8 @@ main()
   foo f;
   
   int (foo::*s)() = &foo::template bar<int>;
+  if ((f.*s)() == 7)
+    return 0;
+  else 
+    return 1;
 }