OSDN Git Service

* class.c (resolve_address_of_overloaded_function): Do conversion
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Dec 1998 15:51:21 +0000 (15:51 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Dec 1998 15:51:21 +0000 (15:51 +0000)
to correct type here, rather than ...
(instantiate_type): Here.
* cp-tree.h (DECL_TEMPLATE_PARM_P): New macro.
(DECL_TEMPLATE_TEMPLATE_PARM_P): Use it.
(decl_template_parm_p): Remove.
* decl.c (pushdecl): Don't set DECL_CONTEXT for a template
paramter.
* lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P.
(push_inline_template_parms_recursive): Set it.
(decl_template_parm_p): Remove.
(check_template_shadow): Use DECL_TEMPLATE_PARM_P.
(process_template_parm): Set it.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/lex.c
gcc/testsuite/g++.old-deja/g++.pt/shadow1.C [new file with mode: 0644]

index b994d6e..6a05c55 100644 (file)
@@ -1,3 +1,20 @@
+1998-12-16  Mark Mitchell  <mark@markmitchell.com>
+
+       * class.c (resolve_address_of_overloaded_function): Do conversion
+       to correct type here, rather than ...
+       (instantiate_type): Here.
+
+       * cp-tree.h (DECL_TEMPLATE_PARM_P): New macro.
+       (DECL_TEMPLATE_TEMPLATE_PARM_P): Use it.
+       (decl_template_parm_p): Remove.
+       * decl.c (pushdecl): Don't set DECL_CONTEXT for a template
+       paramter. 
+       * lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P.
+       (push_inline_template_parms_recursive): Set it.
+       (decl_template_parm_p): Remove.
+       (check_template_shadow): Use DECL_TEMPLATE_PARM_P.
+       (process_template_parm): Set it.
+       
 Wed Dec 16 16:33:58 1998  Dave Brolley  <brolley@cygnus.com>
 
        * lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus
index e3f4544..694ac0b 100644 (file)
@@ -5025,6 +5025,7 @@ resolve_address_of_overloaded_function (target_type,
      are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
      interoperability with most_specialized_instantiation.  */
   tree matches = NULL_TREE;
+  tree fn;
 
   /* By the time we get here, we should be seeing only real
      pointer-to-member types, not the internal POINTER_TYPE to
@@ -5212,8 +5213,20 @@ resolve_address_of_overloaded_function (target_type,
       return error_mark_node;
     }
 
-  /* Good, exactly one match.  */
-  return TREE_PURPOSE (matches);
+  /* Good, exactly one match.  Now, convert it to the correct type.  */
+  fn = TREE_PURPOSE (matches);
+
+  if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
+    return build_unary_op (ADDR_EXPR, fn, 0);
+  else
+    {
+      /* The target must be a REFERENCE_TYPE.  Above, build_unary_op
+        will mark the function as addressed, but here we must do it
+        explicitly.  */
+      mark_addressable (fn);
+
+      return fn;
+    }
 }
 
 /* This function will instantiate the type of the expression given in
@@ -5291,33 +5304,31 @@ instantiate_type (lhstype, rhs, complain)
     case COMPONENT_REF:
       {
        tree field = TREE_OPERAND (rhs, 1);
-       if (TREE_CODE (field) == TREE_LIST)
-         {
-           tree function = instantiate_type (lhstype, field, complain);
-           if (function == error_mark_node)
-             return error_mark_node;
-           my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185);
+       tree r;
+
+       my_friendly_assert (TREE_CODE (field) == TREE_LIST, 0);
 
-           if (! DECL_STATIC_FUNCTION_P (function))
+       r = instantiate_type (lhstype, field, complain);
+
+       if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
+         {
+           tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
+           tree fn = TREE_VALUE (field);
+           if (TREE_CODE (fn) == OVERLOAD)
+             fn = OVL_FUNCTION (fn);
+           if (TREE_CODE (fn) == FUNCTION_DECL)
              {
-               tree t = TREE_TYPE (TREE_OPERAND (rhs, 0));
-               if (TYPE_MAIN_VARIANT (t) == current_class_type)
-                 t = constructor_name (t);
-
-               cp_error ("object-dependent reference to `%D' can only be used in a call",
-                         function);
-               cp_error ("  to form a pointer to member function, say `&%T::%D'",
-                         t, DECL_NAME (function));
-               return error_mark_node;
+               cp_error ("object-dependent reference `%E' can only be used in a call",
+                         DECL_NAME (fn));
+               cp_error ("  to form a pointer to member function, say `&%T::%E'",
+                         t, DECL_NAME (fn));
              }
-
-           mark_used (function);
-           return function;
+           else
+             cp_error ("object-dependent reference can only be used in a call");
+           return error_mark_node;
          }
-
-       /* I could not trigger this code. MvL */
-       my_friendly_abort (980326);
-       return rhs;
+       
+       return r;
       }
 
     case OFFSET_REF:
@@ -5469,27 +5480,7 @@ instantiate_type (lhstype, rhs, complain)
       return rhs;
       
     case ADDR_EXPR:
-      {
-       tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
-       if (fn == error_mark_node)
-         return error_mark_node;
-       mark_addressable (fn);
-       TREE_OPERAND (rhs, 0) = fn;
-       TREE_CONSTANT (rhs) = staticp (fn);
-       if (TYPE_PTRMEMFUNC_P (lhstype))
-         {
-           /* We must use the POINTER_TYPE to METHOD_TYPE on RHS here
-              so that build_ptrmemfunc knows that RHS we have is not
-              already a pointer-to-member constant.  Instead, it is
-              just a ADDR_EXPR over a FUNCTION_DECL.  */
-           TREE_TYPE (rhs) = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
-           rhs = build_ptrmemfunc (TREE_TYPE (rhs), rhs, 0);
-         }
-       else
-         /* Here, things our simple; we have exactly what we need.  */
-         TREE_TYPE (rhs) = lhstype;
-      }
-      return rhs;
+      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
 
     case ENTRY_VALUE_EXPR:
       my_friendly_abort (184);
index 395b24a..cb55b06 100644 (file)
@@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA.  */
 
    Usage of DECL_LANG_FLAG_?:
    0: DECL_ERROR_REPORTED (in VAR_DECL).
+      DECL_TEMPLATE_PARM_P (in CONST_DECL, TYPE_DECL, or TEMPLATE_DECL)
    1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL).
       DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
    2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
@@ -1832,11 +1833,12 @@ extern int flag_new_for_scope;
 #define DECL_TEMPLATE_SPECIALIZATIONS(NODE)     DECL_SIZE(NODE)
 #define DECL_TEMPLATE_INJECT(NODE)     DECL_INITIAL(NODE)
 
-/* Nonzero for TEMPLATE_DECL nodes that represents template template
-   parameters */
+/* Nonzero for a DECL which is actually a template parameter.  */
+#define DECL_TEMPLATE_PARM_P(NODE) \
+  DECL_LANG_FLAG_0 (NODE)
+
 #define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
-  (TREE_CODE (NODE) == TEMPLATE_DECL && TREE_TYPE (NODE) \
-   && TREE_CODE (TREE_TYPE (NODE)) == TEMPLATE_TEMPLATE_PARM)
+  (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))
 
 #define DECL_FUNCTION_TEMPLATE_P(NODE)  \
   (TREE_CODE (NODE) == TEMPLATE_DECL \
@@ -3070,7 +3072,6 @@ extern void do_pushlevel                  PROTO((void));
 extern int is_member_template                   PROTO((tree));
 extern int template_parms_equal                 PROTO((tree, tree));
 extern int comp_template_parms                  PROTO((tree, tree));
-extern int decl_template_parm_p                        PROTO((tree));
 extern int template_class_depth                 PROTO((tree));
 extern int is_specialization_of                 PROTO((tree, tree));
 extern int comp_template_args                   PROTO((tree, tree));
index 356293a..79c38f4 100644 (file)
@@ -3514,15 +3514,23 @@ pushdecl (x)
   register tree name = DECL_ASSEMBLER_NAME (x);
   int need_new_binding = 1;
 
-  if (current_function_decl && x != current_function_decl
-      /* A local declaration for a function doesn't constitute nesting.  */
-      && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x))
-      /* Don't change DECL_CONTEXT of virtual methods.  */
-      && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
-      && !DECL_CONTEXT (x))
-    DECL_CONTEXT (x) = current_function_decl;
-  if (!DECL_CONTEXT (x))
-    DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace);
+  if (DECL_TEMPLATE_PARM_P (x))
+    /* Template parameters have no context; they are not X::T even
+       when declared within a class or namespace.  */
+    ;
+  else
+    {
+      if (current_function_decl && x != current_function_decl
+         /* A local declaration for a function doesn't constitute
+             nesting.  */
+         && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x))
+         /* Don't change DECL_CONTEXT of virtual methods.  */
+         && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
+         && !DECL_CONTEXT (x))
+       DECL_CONTEXT (x) = current_function_decl;
+      if (!DECL_CONTEXT (x))
+       DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace);
+    }
 
   /* Type are looked up using the DECL_NAME, as that is what the rest of the
      compiler wants to use.  */
index e6dd29f..d3b01a9 100644 (file)
@@ -3051,16 +3051,7 @@ do_identifier (token, parsing, args)
            cp_error ("enum `%D' is private", id);
          /* protected is OK, since it's an enum of `this'.  */
        }
-      if (!processing_template_decl
-         /* Really, if we're processing a template, we just want to
-            resolve template parameters, and not enumeration
-            constants.  But, they're hard to tell apart.  (Note that
-            a non-type template parameter may have enumeration type.)
-            Fortunately, there's no harm in resolving *global*
-            enumeration constants, since they can't depend on
-            template parameters.  */
-         || (TREE_CODE (CP_DECL_CONTEXT (id)) == NAMESPACE_DECL
-             && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_PARM_INDEX))
+      if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
        id = DECL_INITIAL (id);
     }
   else
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/shadow1.C b/gcc/testsuite/g++.old-deja/g++.pt/shadow1.C
new file mode 100644 (file)
index 0000000..dfe99c7
--- /dev/null
@@ -0,0 +1,19 @@
+// Build don't link:
+
+template <class T>
+struct S {
+  typedef T X;
+
+  class C {
+    typedef T X;
+  };
+};
+
+template <int I>
+struct S2 {
+  enum { A = I };
+
+  void f() {
+    int A;
+  }
+};