OSDN Git Service

* configure: Regenerate.
[pf3gnuchains/gcc-fork.git] / gcc / cp / search.c
index 2854729..13e252e 100644 (file)
@@ -1,14 +1,14 @@
 /* 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 Free Software Foundation, Inc.
+   1999, 2000, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -17,9 +17,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* High-level class interface.  */
 
@@ -34,6 +33,7 @@ Boston, MA 02111-1307, USA.  */
 #include "rtl.h"
 #include "output.h"
 #include "toplev.h"
+#include "target.h"
 
 static int is_subobject_of_p (tree, tree);
 static tree dfs_lookup_base (tree, void *);
@@ -82,13 +82,13 @@ static int n_contexts_saved;
 struct lookup_base_data_s
 {
   tree t;              /* type being searched.  */
-  tree base;            /* The base type we're looking for.  */
-  tree binfo;           /* Found binfo.  */
-  bool via_virtual;    /* Found via a virtual path.  */
+  tree base;           /* The base type we're looking for.  */
+  tree binfo;          /* Found binfo.  */
+  bool via_virtual;    /* Found via a virtual path.  */
   bool ambiguous;      /* Found multiply ambiguous */
-  bool repeated_base;   /* Whether there are repeated bases in the
+  bool repeated_base;  /* Whether there are repeated bases in the
                            hierarchy.  */
-  bool want_any;       /* Whether we want any matching binfo.  */
+  bool want_any;       /* Whether we want any matching binfo.  */
 };
 
 /* Worker function for lookup_base.  See if we've found the desired
@@ -97,7 +97,7 @@ struct lookup_base_data_s
 static tree
 dfs_lookup_base (tree binfo, void *data_)
 {
-  struct lookup_base_data_s *data = data_;
+  struct lookup_base_data_s *data = (struct lookup_base_data_s *) data_;
 
   if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->base))
     {
@@ -306,7 +306,7 @@ struct dcast_data_s
 static tree
 dfs_dcast_hint_pre (tree binfo, void *data_)
 {
-  struct dcast_data_s *data = data_;
+  struct dcast_data_s *data = (struct dcast_data_s *) data_;
 
   if (BINFO_VIRTUAL_P (binfo))
     data->virt_depth++;
@@ -334,7 +334,7 @@ dfs_dcast_hint_pre (tree binfo, void *data_)
 static tree
 dfs_dcast_hint_post (tree binfo, void *data_)
 {
-  struct dcast_data_s *data = data_;
+  struct dcast_data_s *data = (struct dcast_data_s *) data_;
 
   if (BINFO_VIRTUAL_P (binfo))
     data->virt_depth--;
@@ -792,8 +792,8 @@ friend_accessible_p (tree scope, tree decl, tree binfo)
     if (protected_accessible_p (decl, TREE_VALUE (t), binfo))
       return 1;
 
-  /* Nested classes are implicitly friends of their enclosing types, as
-     per core issue 45 (this is a change from the standard).  */
+  /* Nested classes have the same access as their enclosing types, as
+     per DR 45 (this is a change from the standard).  */
   if (TYPE_P (scope))
     for (t = TYPE_CONTEXT (scope); t && TYPE_P (t); t = TYPE_CONTEXT (t))
       if (protected_accessible_p (decl, t, binfo))
@@ -872,8 +872,12 @@ accessible_p (tree type, tree decl, bool consider_local_p)
   /* In a template declaration, we cannot be sure whether the
      particular specialization that is instantiated will be a friend
      or not.  Therefore, all access checks are deferred until
-     instantiation.  */
-  if (processing_template_decl)
+     instantiation.  However, PROCESSING_TEMPLATE_DECL is set in the
+     parameter list for a template (because we may see dependent types
+     in default arguments for template parameters), and access
+     checking should be performed in the outermost parameter list.  */
+  if (processing_template_decl
+      && (!processing_template_parmlist || processing_template_decl > 1))
     return 1;
 
   if (!TYPE_P (type))
@@ -1084,8 +1088,8 @@ lookup_field_r (tree binfo, void *data)
        nval = NULL_TREE;
       if (!nval && CLASSTYPE_NESTED_UTDS (type) != NULL)
        {
-          binding_entry e = binding_table_find (CLASSTYPE_NESTED_UTDS (type),
-                                                lfi->name);
+         binding_entry e = binding_table_find (CLASSTYPE_NESTED_UTDS (type),
+                                               lfi->name);
          if (e != NULL)
            nval = TYPE_MAIN_DECL (e->type);
          else
@@ -1196,6 +1200,9 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
 
   const char *errstr = 0;
 
+  if (name == error_mark_node)
+    return NULL_TREE;
+
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
   if (TREE_CODE (xbasetype) == TREE_BINFO)
@@ -1205,7 +1212,8 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
     }
   else
     {
-      gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)));
+      if (!IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
+       return NULL_TREE;
       type = xbasetype;
       xbasetype = NULL_TREE;
     }
@@ -1248,15 +1256,33 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
   /* [class.access]
 
      In the case of overloaded function names, access control is
-     applied to the function selected by overloaded resolution.  */
-  if (rval && protect && !is_overloaded_fn (rval))
-    perform_or_defer_access_check (basetype_path, rval);
+     applied to the function selected by overloaded resolution.  
+
+     We cannot check here, even if RVAL is only a single non-static
+     member function, since we do not know what the "this" pointer
+     will be.  For:
+
+        class A { protected: void f(); };
+        class B : public A { 
+          void g(A *p) {
+            f(); // OK
+            p->f(); // Not OK.
+          }
+        };
+
+    only the first call to "f" is valid.  However, if the function is
+    static, we can check.  */
+  if (rval && protect 
+      && !really_overloaded_fn (rval)
+      && !(TREE_CODE (rval) == FUNCTION_DECL
+          && DECL_NONSTATIC_MEMBER_FUNCTION_P (rval)))
+    perform_or_defer_access_check (basetype_path, rval, rval);
 
   if (errstr && protect)
     {
       error (errstr, name, type);
       if (lfi.ambiguous)
-        print_candidates (lfi.ambiguous);
+       print_candidates (lfi.ambiguous);
       rval = error_mark_node;
     }
 
@@ -1475,14 +1501,14 @@ adjust_result_of_qualified_name_lookup (tree decl,
                                        tree qualifying_scope,
                                        tree context_class)
 {
-  if (context_class && CLASS_TYPE_P (qualifying_scope)
+  if (context_class && context_class != error_mark_node
+      && CLASS_TYPE_P (context_class)
+      && CLASS_TYPE_P (qualifying_scope)
       && DERIVED_FROM_P (qualifying_scope, context_class)
       && BASELINK_P (decl))
     {
       tree base;
 
-      gcc_assert (CLASS_TYPE_P (context_class));
-
       /* Look for the QUALIFYING_SCOPE as a base of the CONTEXT_CLASS.
         Because we do not yet know which function will be chosen by
         overload resolution, we cannot yet check either accessibility
@@ -1655,8 +1681,8 @@ dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
       if (!BINFO_INHERITANCE_CHAIN (binfo))
        {
          /* We are at the top of the hierarchy, and can use the
-             CLASSTYPE_VBASECLASSES list for unmarking the virtual
-             bases.  */
+            CLASSTYPE_VBASECLASSES list for unmarking the virtual
+            bases.  */
          VEC(tree,gc) *vbases;
          unsigned ix;
          tree base_binfo;
@@ -1710,8 +1736,8 @@ dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
        continue;
 
       /* If the base is inherited via private or protected
-        inheritance, then we can't see it, unless we are a friend of
-        the current binfo.  */
+        inheritance, then we can't see it, unless we are a friend of
+        the current binfo.  */
       if (BINFO_BASE_ACCESS (binfo, ix) != access_public_node)
        {
          tree scope;
@@ -1763,8 +1789,8 @@ dfs_walk_once_accessible (tree binfo, bool friends_p,
       if (!BINFO_INHERITANCE_CHAIN (binfo))
        {
          /* We are at the top of the hierarchy, and can use the
-             CLASSTYPE_VBASECLASSES list for unmarking the virtual
-             bases.  */
+            CLASSTYPE_VBASECLASSES list for unmarking the virtual
+            bases.  */
          VEC(tree,gc) *vbases;
          unsigned ix;
          tree base_binfo;
@@ -1839,9 +1865,9 @@ check_final_overrider (tree overrider, tree basefn)
            fail = 2;
          else
            {
-             cp_warning_at ("deprecated covariant return type for %q#D",
+             warning (0, "deprecated covariant return type for %q+#D",
                             overrider);
-             cp_warning_at ("  overriding %q#D", basefn);
+             warning (0, "  overriding %q+#D", basefn);
            }
        }
       else
@@ -1855,14 +1881,13 @@ check_final_overrider (tree overrider, tree basefn)
     {
       if (fail == 1)
        {
-         cp_error_at ("invalid covariant return type for %q#D", overrider);
-         cp_error_at ("  overriding %q#D", basefn);
+         error ("invalid covariant return type for %q+#D", overrider);
+         error ("  overriding %q+#D", basefn);
        }
       else
        {
-         cp_error_at ("conflicting return type specified for %q#D",
-                      overrider);
-         cp_error_at ("  overriding %q#D", basefn);
+         error ("conflicting return type specified for %q+#D", overrider);
+         error ("  overriding %q+#D", basefn);
        }
       DECL_INVALID_OVERRIDER_P (overrider) = 1;
       return 0;
@@ -1871,8 +1896,17 @@ check_final_overrider (tree overrider, tree basefn)
   /* Check throw specifier is at least as strict.  */
   if (!comp_except_specs (base_throw, over_throw, 0))
     {
-      cp_error_at ("looser throw specifier for %q#F", overrider);
-      cp_error_at ("  overriding %q#F", basefn);
+      error ("looser throw specifier for %q+#F", overrider);
+      error ("  overriding %q+#F", basefn);
+      DECL_INVALID_OVERRIDER_P (overrider) = 1;
+      return 0;
+    }
+
+  /* Check for conflicting type attributes.  */
+  if (!targetm.comp_type_attributes (over_type, base_type))
+    {
+      error ("conflicting type attributes specified for %q+#D", overrider);
+      error ("  overriding %q+#D", basefn);
       DECL_INVALID_OVERRIDER_P (overrider) = 1;
       return 0;
     }
@@ -1903,7 +1937,7 @@ look_for_overrides (tree type, tree fndecl)
       tree basetype = BINFO_TYPE (base_binfo);
 
       if (TYPE_POLYMORPHIC_P (basetype))
-        found += look_for_overrides_r (basetype, fndecl);
+       found += look_for_overrides_r (basetype, fndecl);
     }
   return found;
 }
@@ -1931,21 +1965,21 @@ look_for_overrides_here (tree type, tree fndecl)
       tree fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
 
       for (; fns; fns = OVL_NEXT (fns))
-        {
-          tree fn = OVL_CURRENT (fns);
+       {
+         tree fn = OVL_CURRENT (fns);
 
-          if (!DECL_VIRTUAL_P (fn))
-            /* Not a virtual.  */;
-          else if (DECL_CONTEXT (fn) != type)
-            /* Introduced with a using declaration.  */;
+         if (!DECL_VIRTUAL_P (fn))
+           /* Not a virtual.  */;
+         else if (DECL_CONTEXT (fn) != type)
+           /* Introduced with a using declaration.  */;
          else if (DECL_STATIC_FUNCTION_P (fndecl))
            {
              tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
              tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
-             if (compparms (TREE_CHAIN (btypes), dtypes))
+             if (compparms (TREE_CHAIN (btypes), dtypes))
                return fn;
-            }
-          else if (same_signature_p (fndecl, fn))
+           }
+         else if (same_signature_p (fndecl, fn))
            return fn;
        }
     }
@@ -1965,8 +1999,8 @@ look_for_overrides_r (tree type, tree fndecl)
        {
          /* A static member function cannot match an inherited
             virtual member function.  */
-         cp_error_at ("%q#D cannot be declared", fndecl);
-         cp_error_at ("  since %q#D declared in base class", fn);
+         error ("%q+#D cannot be declared", fndecl);
+         error ("  since %q+#D declared in base class", fn);
        }
       else
        {
@@ -2039,6 +2073,10 @@ maybe_suppress_debug_info (tree t)
   /* We might have set this earlier in cp_finish_decl.  */
   TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 0;
 
+  /* Always emit the information for each class every time. */
+  if (flag_emit_class_debug_always)
+    return;
+
   /* If we already know how we're handling this class, handle debug info
      the same way.  */
   if (CLASSTYPE_INTERFACE_KNOWN (t))
@@ -2149,7 +2187,7 @@ check_hidden_convs (tree binfo, int virtual_depth, int virtualness,
   if (virtual_depth || virtualness)
     {
      /* In a virtual hierarchy, we could be hidden, or could hide a
-        conversion function on the other_convs list.  */
+       conversion function on the other_convs list.  */
       for (level = other_convs; level; level = TREE_CHAIN (level))
        {
          int we_hide_them;
@@ -2352,7 +2390,7 @@ lookup_conversions_r (tree binfo,
     {
       parent_tpl_convs = tree_cons (binfo, my_tpl_convs, parent_tpl_convs);
       if (virtual_depth)
-       TREE_STATIC (parent_convs) = 1;
+       TREE_STATIC (parent_tpl_convs) = 1;
     }
 
   child_convs = other_convs;