OSDN Git Service

Fix PR c++/45383
[pf3gnuchains/gcc-fork.git] / gcc / cp / search.c
index ecc7926..c02800c 100644 (file)
@@ -1,7 +1,7 @@
 /* Breadth-first and depth-first routines for
    searching multiple-inheritance lattice for GNU C++.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -29,9 +29,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "cp-tree.h"
-#include "obstack.h"
+#include "intl.h"
 #include "flags.h"
-#include "rtl.h"
 #include "output.h"
 #include "toplev.h"
 #include "target.h"
@@ -63,7 +62,6 @@ static tree dfs_access_in_type (tree, void *);
 static access_kind access_in_type (tree, tree);
 static int protected_accessible_p (tree, tree, tree);
 static int friend_accessible_p (tree, tree, tree);
-static int template_self_reference_p (tree, tree);
 static tree dfs_get_pure_virtuals (tree, void *);
 
 \f
@@ -172,7 +170,7 @@ accessible_base_p (tree t, tree base, bool consider_local_p)
      public typedef created in the scope of every class.  */
   decl = TYPE_FIELDS (base);
   while (!DECL_SELF_REFERENCE_P (decl))
-    decl = TREE_CHAIN (decl);
+    decl = DECL_CHAIN (decl);
   while (ANON_AGGR_TYPE_P (t))
     t = TYPE_CONTEXT (t);
   return accessible_p (t, decl, consider_local_p);
@@ -214,9 +212,11 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
       t_binfo = TYPE_BINFO (t);
     }
 
-  base = complete_type (TYPE_MAIN_VARIANT (base));
+  base = TYPE_MAIN_VARIANT (base);
 
-  if (t_binfo)
+  /* If BASE is incomplete, it can't be a base of T--and instantiating it
+     might cause an error.  */
+  if (t_binfo && CLASS_TYPE_P (base) && COMPLETE_OR_OPEN_TYPE_P (base))
     {
       struct lookup_base_data_s data;
 
@@ -395,12 +395,10 @@ lookup_field_1 (tree type, tree name, bool want_type)
        The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME.  */
     return NULL_TREE;
 
-  if (TYPE_NAME (type)
-      && DECL_LANG_SPECIFIC (TYPE_NAME (type))
-      && DECL_SORTED_FIELDS (TYPE_NAME (type)))
+  if (CLASSTYPE_SORTED_FIELDS (type))
     {
-      tree *fields = &DECL_SORTED_FIELDS (TYPE_NAME (type))->elts[0];
-      int lo = 0, hi = DECL_SORTED_FIELDS (TYPE_NAME (type))->len;
+      tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0];
+      int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len;
       int i;
 
       while (lo < hi)
@@ -449,7 +447,7 @@ lookup_field_1 (tree type, tree name, bool want_type)
 #ifdef GATHER_STATISTICS
   n_calls_lookup_field_1++;
 #endif /* GATHER_STATISTICS */
-  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
     {
 #ifdef GATHER_STATISTICS
       n_fields_searched++;
@@ -954,24 +952,6 @@ struct lookup_field_info {
   const char *errstr;
 };
 
-/* Within the scope of a template class, you can refer to the to the
-   current specialization with the name of the template itself.  For
-   example:
-
-     template <typename T> struct S { S* sp; }
-
-   Returns nonzero if DECL is such a declaration in a class TYPE.  */
-
-static int
-template_self_reference_p (tree type, tree decl)
-{
-  return  (CLASSTYPE_USE_TEMPLATE (type)
-          && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
-          && TREE_CODE (decl) == TYPE_DECL
-          && DECL_ARTIFICIAL (decl)
-          && DECL_NAME (decl) == constructor_name (type));
-}
-
 /* Nonzero for a class member means that it is shared between all objects
    of that class.
 
@@ -990,6 +970,7 @@ shared_member_p (tree t)
     return 1;
   if (is_overloaded_fn (t))
     {
+      t = get_fns (t);
       for (; t; t = OVL_NEXT (t))
        {
          tree fn = OVL_CURRENT (t);
@@ -1091,11 +1072,6 @@ lookup_field_r (tree binfo, void *data)
        }
     }
 
-  /* You must name a template base class with a template-id.  */
-  if (!same_type_p (type, lfi->type)
-      && template_self_reference_p (type, nval))
-    goto done;
-
   /* If the lookup already found a match, and the new value doesn't
      hide the old one, we might have an ambiguity.  */
   if (lfi->rval_binfo
@@ -1124,7 +1100,7 @@ lookup_field_r (tree binfo, void *data)
          /* Add the new value.  */
          lfi->ambiguous = tree_cons (NULL_TREE, nval, lfi->ambiguous);
          TREE_TYPE (lfi->ambiguous) = error_mark_node;
-         lfi->errstr = "request for member %qD is ambiguous";
+         lfi->errstr = G_("request for member %qD is ambiguous");
        }
     }
   else
@@ -1359,7 +1335,7 @@ lookup_conversion_operator (tree class_type, tree type)
 }
 
 /* TYPE is a class type. Return the index of the fields within
-   the method vector with name NAME, or -1 is no such field exists.  */
+   the method vector with name NAME, or -1 if no such field exists.  */
 
 int
 lookup_fnfields_1 (tree type, tree name)
@@ -1382,10 +1358,16 @@ lookup_fnfields_1 (tree type, tree name)
            lazily_declare_fn (sfk_constructor, type);
          if (CLASSTYPE_LAZY_COPY_CTOR (type))
            lazily_declare_fn (sfk_copy_constructor, type);
+         if (CLASSTYPE_LAZY_MOVE_CTOR (type))
+           lazily_declare_fn (sfk_move_constructor, type);
+       }
+      else if (name == ansi_assopname (NOP_EXPR))
+       {
+         if (CLASSTYPE_LAZY_COPY_ASSIGN (type))
+           lazily_declare_fn (sfk_copy_assignment, type);
+         if (CLASSTYPE_LAZY_MOVE_ASSIGN (type))
+           lazily_declare_fn (sfk_move_assignment, type);
        }
-      else if (name == ansi_assopname(NOP_EXPR)
-              && CLASSTYPE_LAZY_ASSIGNMENT_OP (type))
-       lazily_declare_fn (sfk_assignment_operator, type);
       else if ((name == dtor_identifier
                || name == base_dtor_identifier
                || name == complete_dtor_identifier
@@ -1463,6 +1445,18 @@ lookup_fnfields_1 (tree type, tree name)
   return -1;
 }
 
+/* TYPE is a class type. Return the field within the method vector with
+   name NAME, or NULL_TREE if no such field exists.  */
+
+tree
+lookup_fnfields_slot (tree type, tree name)
+{
+  int ix = lookup_fnfields_1 (type, name);
+  if (ix < 0)
+    return NULL_TREE;
+  return VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
+}
+
 /* Like lookup_fnfields_1, except that the name is extracted from
    FUNCTION, which is a FUNCTION_DECL or a TEMPLATE_DECL.  */
 
@@ -1888,7 +1882,7 @@ check_final_overrider (tree overrider, tree basefn)
     }
 
   /* Check throw specifier is at least as strict.  */
-  if (!comp_except_specs (base_throw, over_throw, 0))
+  if (!comp_except_specs (base_throw, over_throw, ce_derived))
     {
       error ("looser throw specifier for %q+#F", overrider);
       error ("  overriding %q+#F", basefn);
@@ -1911,6 +1905,7 @@ check_final_overrider (tree overrider, tree basefn)
        {
          error ("deleted function %q+D", overrider);
          error ("overriding non-deleted function %q+D", basefn);
+         maybe_explain_implicit_delete (overrider);
        }
       else
        {
@@ -1940,6 +1935,11 @@ look_for_overrides (tree type, tree fndecl)
   int ix;
   int found = 0;
 
+  /* A constructor for a class T does not override a function T
+     in a base class.  */
+  if (DECL_CONSTRUCTOR_P (fndecl))
+    return 0;
+
   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
     {
       tree basetype = BINFO_TYPE (base_binfo);