class.c (instantiate_type): Handle pointer-to-members where the member is a template.
authorMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 7 Jun 1998 12:13:54 +0000 (12:13 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 7 Jun 1998 12:13:54 +0000 (12:13 +0000)
* class.c (instantiate_type): Handle pointer-to-members where the
member is a template.
* init.c (build_offset_ref): Likewise.
* typeck.c (build_unary_op): Likewise.

From-SVN: r20269

gcc/cp/class.c
gcc/cp/init.c
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C [new file with mode: 0644]

index 900253d408cbb78e5ebe6e613b49063446fe8551..c1f58bd5407be48ebf99c604230179c88997c6c0 100644 (file)
@@ -5092,6 +5092,21 @@ 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 TEMPLATE_ID_EXPR:
       {
        explicit_targs = TREE_OPERAND (rhs, 1);
@@ -5101,6 +5116,7 @@ instantiate_type (lhstype, rhs, complain)
       my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);
 
     case OVERLOAD:
+    overload:
       {
        tree elem, elems;
 
@@ -5112,7 +5128,8 @@ instantiate_type (lhstype, rhs, complain)
        if (lhstype == error_mark_node)
          return lhstype;
 
-       if (TREE_CODE (lhstype) != FUNCTION_TYPE)
+       if (TREE_CODE (lhstype) != FUNCTION_TYPE
+           && TREE_CODE (lhstype) != METHOD_TYPE)
          {
            rhs = DECL_NAME (OVL_FUNCTION (rhs));
            if (complain)
index 4eca6b630576e4d3dc1567929d57d8a1fd87d023..b7b74c0ec96eb1f0a6a5bb9dfc6efa7c7a4069a9 100644 (file)
@@ -1615,14 +1615,15 @@ build_offset_ref (type, name)
   int dtor = 0;
 
   /* class templates can come in as TEMPLATE_DECLs here.  */
-  if (TREE_CODE (name) != IDENTIFIER_NODE)
+  if (TREE_CODE (name) == TEMPLATE_DECL)
     return name;
 
   if (type == std_node)
     return do_scoped_id (name, 0);
 
-  if (processing_template_decl || uses_template_parms (type))
-    return build_min_nt (SCOPE_REF, type, name);
+  if (processing_template_decl || uses_template_parms (type)
+      || TREE_CODE (name) == TEMPLATE_ID_EXPR)
+    return build_min (SCOPE_REF, unknown_type_node, type, name);
 
   /* Handle namespace names fully here.  */
   if (TREE_CODE (type) == NAMESPACE_DECL)
index 785c33bb5d2bd4f4def8425a8ca45ebf3cd4e367..f394f403b7f790ed5e4ebe5ea5edc5e30159e24f 100644 (file)
@@ -4560,7 +4560,9 @@ build_unary_op (code, xarg, noconvert)
          return build1 (ADDR_EXPR, unknown_type_node, arg);
        }
 
-      if (TREE_CODE (arg) == OVERLOAD)
+      if (TREE_CODE (arg) == OVERLOAD 
+         || (TREE_CODE (arg) == SCOPE_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)
        {
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C
new file mode 100644 (file)
index 0000000..3cd9c2b
--- /dev/null
@@ -0,0 +1,16 @@
+// Build don't run:
+
+class foo
+{
+public:
+  template<class T>
+  T bar() {}
+};
+
+int
+main()
+{
+  foo f;
+  
+  int (foo::*s)() = &foo::template bar<int>;
+}