]> gcc.gnu.org Git - gcc.git/commitdiff
class.c (add_method): Fix documentation to reflect previous changes.
authorMark Mitchell <mark@markmitchell.com>
Fri, 16 Oct 1998 12:08:01 +0000 (12:08 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 16 Oct 1998 12:08:01 +0000 (12:08 +0000)
* class.c (add_method): Fix documentation to reflect previous
changes.  Check for duplicate method declarations here.
* decl.c (decls_match): Handle FUNCTION_DECL vs TEMPLATE_DECL
correctly; such things never match.
(grokfndecl): Don't look for duplicate methods here.
* decl2.c (check_classfn): Don't assume names are mangled.
Don't add bogus member function declarations to a class before the
class type is complete.
(grokfield): Reformat error message.
* method.c (set_mangled_name_for_decl): Don't mangle names while
procesing_template_decl.

From-SVN: r23132

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/method.c
gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C
gcc/testsuite/g++.old-deja/g++.pt/memtemp78.C [new file with mode: 0644]

index 1b93d0206fabf983557f8c691e9ab48a7c413d94..50694eeab09510bfa77649769c2a68157cddb5e1 100644 (file)
@@ -1,3 +1,17 @@
+1998-10-16  Mark Mitchell  <mark@markmitchell.com>
+
+       * class.c (add_method): Fix documentation to reflect previous
+       changes.  Check for duplicate method declarations here.
+       * decl.c (decls_match): Handle FUNCTION_DECL vs TEMPLATE_DECL
+       correctly; such things never match.
+       (grokfndecl): Don't look for duplicate methods here.
+       * decl2.c (check_classfn): Don't assume names are mangled.
+       Don't add bogus member function declarations to a class before the
+       class type is complete.
+       (grokfield): Reformat error message.
+       * method.c (set_mangled_name_for_decl): Don't mangle names while
+       procesing_template_decl.
+       
 1998-10-16  Jason Merrill  <jason@yorick.cygnus.com>
 
        * typeck.c (build_indirect_ref): Complain about a pointer to data
index d5032960625443ea318085506e30ff9ca31caa26..2bc8f375e55e6c8f96a0f7ff8de99e1318f07bba 100644 (file)
@@ -1109,12 +1109,10 @@ free_method_vec (vec)
   free_method_vecs = vec;
 }
 
-/* Add method METHOD to class TYPE.  This is used when a method
-   has been defined which did not initially appear in the class definition,
-   and helps cut down on spurious error messages.
+/* Add method METHOD to class TYPE.
 
-   FIELDS is the entry in the METHOD_VEC vector entry of the class type where
-   the method should be added.  */
+   If non-NULL, FIELDS is the entry in the METHOD_VEC vector entry of
+   the class type where the method should be added.  */
 
 void
 add_method (type, fields, method)
@@ -1184,6 +1182,52 @@ add_method (type, fields, method)
              len = 2 * len;
              method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec;
            }
+         else if (template_class_depth (type))
+           /* TYPE is a template class.  Don't issue any errors now;
+              wait until instantiation time to complain.  */
+             ;
+         else
+           {
+             tree fns;
+
+             /* Check to see if we've already got this method.  */
+             for (fns = TREE_VEC_ELT (method_vec, i);
+                  fns;
+                  fns = OVL_NEXT (fns))
+               {
+                 tree fn = OVL_CURRENT (fns);
+                
+                 if (TREE_CODE (fn) != TREE_CODE (method))
+                   continue;
+
+                 if (TREE_CODE (method) != TEMPLATE_DECL)
+                   {
+                     /* Since this is an ordinary function in a
+                        non-template class, it's mangled name can be
+                        used as a unique identifier.  This technique
+                        is only an optimization; we would get the
+                        same results if we just used decls_match
+                        here.  */
+                     if (DECL_ASSEMBLER_NAME (fn) 
+                         != DECL_ASSEMBLER_NAME (method))
+                       continue;
+                   }
+                 else if (!decls_match (fn, method))
+                   continue;
+
+                 /* There has already been a declaration of this
+                    method or member template.  */
+                 cp_error_at ("`%D' has already been declared in `%T'", 
+                              method, type);
+
+                 /* We don't call duplicate_decls here to merege the
+                    declarations because that will confuse things if
+                    the methods have inline definitions In
+                    particular, we will crash while processing the
+                    definitions.  */
+                 return;
+               }
+           }
 
          if (IDENTIFIER_TYPENAME_P (DECL_NAME (method)))
            {
@@ -1226,6 +1270,9 @@ add_method (type, fields, method)
                }
            }
 
+         /* Create RTL for the METHOD.  */
+         make_decl_rtl (method, NULL_PTR, 1);
+
          /* Actually insert the new method.  */
          TREE_VEC_ELT (method_vec, i) 
            = build_overload (method, TREE_VEC_ELT (method_vec, i));
index 75a37a651d494f712a7a882476b523f7deaf35f4..f296fa2bbb4119fea0084707c60d8d0b09247115 100644 (file)
@@ -2511,8 +2511,12 @@ decls_match (newdecl, olddecl)
 {
   int types_match;
 
-  if (TREE_CODE (newdecl) == FUNCTION_DECL
-      && TREE_CODE (olddecl) == FUNCTION_DECL)
+  if (TREE_CODE (newdecl) != TREE_CODE (olddecl))
+    /* If the two DECLs are not even the same kind of thing, we're not
+       interested in their types.  */
+    return 0;
+
+  if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
       tree f1 = TREE_TYPE (newdecl);
       tree f2 = TREE_TYPE (olddecl);
@@ -2568,8 +2572,7 @@ decls_match (newdecl, olddecl)
       else
        types_match = 0;
     }
-  else if (TREE_CODE (newdecl) == TEMPLATE_DECL
-          && TREE_CODE (olddecl) == TEMPLATE_DECL)
+  else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
       if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
                                DECL_TEMPLATE_PARMS (olddecl)))
@@ -8184,22 +8187,6 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        }
       if (! grok_ctor_properties (ctype, decl))
        return error_mark_node;
-
-      if (check == 0 && ! current_function_decl)
-       {
-         /* Assembler names live in the global namespace. */
-         tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl));
-         if (tmp == NULL_TREE)
-           SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl), decl);
-         else if (TREE_CODE (tmp) != TREE_CODE (decl))
-           cp_error ("inconsistent declarations for `%D'", decl);
-         else
-           {
-             duplicate_decls (decl, tmp);
-             decl = tmp;
-           }
-         make_decl_rtl (decl, NULL_PTR, 1);
-       }
     }
   else
     {
@@ -8248,37 +8235,6 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
       if (ctype == NULL_TREE || check)
        return decl;
 
-      /* Now install the declaration of this function so that others may
-        find it (esp. its DECL_FRIENDLIST).  Don't do this for local class
-        methods, though.  */
-      if (! current_function_decl)
-       {
-         if (!DECL_TEMPLATE_SPECIALIZATION (decl))
-           {
-             /* We don't do this for specializations since the
-                equivalent checks will be done later.  Also, at this
-                point the DECL_ASSEMBLER_NAME is not yet fully
-                accurate.  */
-
-             /* FIXME: this should only need to look at
-                IDENTIFIER_GLOBAL_VALUE.  */
-             tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0);
-             if (tmp == NULL_TREE)
-               SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl), decl);
-             else if (TREE_CODE (tmp) != TREE_CODE (decl))
-               cp_error ("inconsistent declarations for `%D'", decl);
-             else
-               {
-                 duplicate_decls (decl, tmp);
-                 decl = tmp;
-               }
-           }
-
-         if (attrlist)
-           cplus_decl_attributes (decl, TREE_PURPOSE (attrlist),
-                                  TREE_VALUE (attrlist));
-         make_decl_rtl (decl, NULL_PTR, 1);
-       }
       if (virtualp)
        {
          DECL_VIRTUAL_P (decl) = 1;
index 92e01fee87b7ee00420cab95286da813dcfc7c5c..f20d6f2743f8ccd2020e4514b81768d7d8141995 100644 (file)
@@ -1383,14 +1383,19 @@ check_classfn (ctype, function)
                   fndecls = OVL_NEXT (fndecls))
                {
                  fndecl = OVL_CURRENT (fndecls);
-                 /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL is
+                 /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or
+                    for a for member function of a template class, is
                     not mangled, so the check below does not work
-                    correctly in that case.  Since mangled destructor names
-                    do not include the type of the arguments, we
-                    can't use this short-cut for them, either.  */
-                 if (TREE_CODE (function) != TEMPLATE_DECL
-                     && TREE_CODE (fndecl) != TEMPLATE_DECL
-                     && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))
+                    correctly in that case.  Since mangled destructor
+                    names do not include the type of the arguments,
+                    we can't use this short-cut for them, either.
+                    (It's not legal to declare arguments for a
+                    destructor, but some people try.)  */
+                 if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))
+                     && (DECL_ASSEMBLER_NAME (function)
+                         != DECL_NAME (function))
+                     && (DECL_ASSEMBLER_NAME (fndecl)
+                         != DECL_NAME (fndecl))
                      && (DECL_ASSEMBLER_NAME (function) 
                          == DECL_ASSEMBLER_NAME (fndecl)))
                    return fndecl;
@@ -1467,8 +1472,11 @@ check_classfn (ctype, function)
     }
 
   /* If we did not find the method in the class, add it to avoid
-     spurious errors.  */
-  add_method (ctype, methods, function);
+     spurious errors (unless the CTYPE is not yet defined, in which
+     case we'll only confuse ourselves when the function is declared
+     properly within the class.  */
+  if (TYPE_SIZE (ctype))
+    add_method (ctype, methods, function);
   return NULL_TREE;
 }
 
@@ -1573,8 +1581,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
 
   if (DECL_IN_AGGR_P (value))
     {
-      cp_error ("`%D' is already defined in the class %T", value,
-                 DECL_CONTEXT (value));
+      cp_error ("`%D' is already defined in `%T'", value,
+               DECL_CONTEXT (value));
       return void_type_node;
     }
 
index 82a886c2377774b07ff98edce92a1bd2a6810dff..400aead4d46f4f0beeeb2dbcc8d9b74169914b97 100644 (file)
@@ -1662,7 +1662,13 @@ void
 set_mangled_name_for_decl (decl)
      tree decl;
 {
-  tree parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
+  tree parm_types;
+
+  if (processing_template_decl)
+    /* There's no need to mangle the name of a template function.  */
+    return;
+
+  parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
 
   if (DECL_STATIC_FUNCTION_P (decl))
     parm_types = 
index a60a2d7e150dffff2e94fea251f7026d8b934091..e63d43cbec9cf60438708506a100d87119f385d3 100644 (file)
@@ -31,16 +31,16 @@ class C
 class D
 {
 public:
-  int foo2() {return b;}  // WARNING - 
-  int foo2() {return b;}  // WARNING - 
+  int foo2() {return b;}  
+  int foo2() {return b;}  // ERROR - 
   int b;
 };
 
 class E
 {
 public:
-  int foo2(); // WARNING - 
-  int foo2(); // WARNING - 
+  int foo2(); 
+  int foo2(); // ERROR - 
   int b;
 };
 
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp78.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp78.C
new file mode 100644 (file)
index 0000000..945e7ff
--- /dev/null
@@ -0,0 +1,56 @@
+// Build don't link:
+
+struct A 
+{
+  void f() {}
+
+  template <class U>
+  void f() {}
+};
+
+
+template <class T>
+struct B
+{
+  void f() {}
+
+  template <class U>
+  void f() {}
+};
+
+template struct B<int>;
+
+struct C 
+{
+  template <class U>
+  void f() {}
+
+  template <class U>
+  void f() {}  // ERROR - redeclaration
+};
+
+
+template <class T, class U>
+struct D
+{
+  void f(T);
+  void f(U);
+};
+
+template struct D<int, double>;
+
+template <class T, class U>
+struct D2
+{
+  void f(T);
+  void f(U); // ERROR - redeclaration 
+};
+
+template struct D2<int, int>; 
+
+struct E
+{
+  void f(); 
+  void f(); // ERROR - redeclaration
+};
+
This page took 0.103943 seconds and 5 git commands to generate.